I am building a JsonResponse view in Django 1.7 via Python 2.7.9 for tracking requests made through the EasyPost API. The view:
我正在通过Python 2.7.9在Django 1.7中构建一个JsonResponse视图,用于跟踪通过EasyPost API发出的请求。风景:
def TrackingTable(request, trackingnumber):
easypost.api_key = 'xxxxxxxxxxxxxxxxxxx'
tracker = easypost.Tracker.create(
tracking_code='EZ3000000003',
carrier="UPS"
)
tracking = tracker['tracking_details']
return JsonResponse({"tracking":tracking, "url":request.get_full_path})
When this wasn't working I tried to see if the issue was related to Json. So i went in manually and tried to pull out JSON values since the EasyPost API (and response object) shows JSON as the output:
当这不起作用时,我试着看看问题是否与Json有关。所以我手动进入并尝试提取JSON值,因为EasyPost API(和响应对象)显示JSON作为输出:
easypost.api_key = 'xxxxxxxxxxxxxxxxxxx'
tracker = easypost.Tracker.create(
tracking_code='EZ3000000003',
carrier="UPS"
)
>>> tracker
<Tracker Tracker at 0x7f467982be50> JSON: {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"carrier": "UPS",
"created_at": "2015-03-18T15:48:43Z",
"est_delivery_date": "2014-08-27T00:00:00Z",
"id": "trk_qufcxYmC",
"mode": "test",
"object": "Tracker",
"shipment_id": null,
"signed_by": null,
"status": "out_for_delivery",
"tracking_code": "EZ3000000003",
"tracking_details": [
{
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"datetime": "2014-08-21T14:24:00Z",
"message": "BILLING INFORMATION RECEIVED",
"object": "TrackingDetail",
"status": "pre_transit",
"tracking_location": {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"city": null,
"country": null,
"object": "TrackingLocation",
"state": null,
"zip": null
}
},
{
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"datetime": "2014-08-21T14:48:00Z",
"message": "ORIGIN SCAN",
"object": "TrackingDetail",
"status": "in_transit",
"tracking_location": {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"city": "SOUTH SAN FRANCISCO",
"country": "US",
"object": "TrackingLocation",
"state": "CA",
"zip": null
}
},
{
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"datetime": "2014-08-22T08:51:00Z",
"message": "DEPARTURE SCAN",
"object": "TrackingDetail",
"status": "in_transit",
"tracking_location": {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"city": "SOUTH SAN FRANCISCO",
"country": "US",
"object": "TrackingLocation",
"state": "CA",
"zip": null
}
},
{
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"datetime": "2014-08-23T09:31:00Z",
"message": "ARRIVAL SCAN",
"object": "TrackingDetail",
"status": "in_transit",
"tracking_location": {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"city": "SAN FRANCISCO",
"country": "US",
"object": "TrackingLocation",
"state": "CA",
"zip": null
}
},
{
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"datetime": "2014-08-24T08:10:00Z",
"message": "OUT FOR DELIVERY",
"object": "TrackingDetail",
"status": "out_for_delivery",
"tracking_location": {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"city": "SAN FRANCISCO",
"country": "US",
"object": "TrackingLocation",
"state": "CA",
"zip": null
}
}
],
"updated_at": "2015-03-18T15:48:43Z",
"weight": 17.6
}>
"tracker
" is a class object
“tracker”是一个类对象
>>> print type(tracker)
<class 'easypost.Tracker'>
Attempt to convert class to dicitonary:
尝试将类转换为dicitonary:
>>> this = dict(tracker)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/easypost/__init__.py", line 359, in keys
return self._values.keys()
AttributeError: 'set' object has no attribute 'keys'
Attempt to dump to JSON:
尝试转储到JSON:
>>> json.dumps(tracker)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/usr/local/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/local/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Tracker Tracker at 0x7f467982be50> JSON: {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"carrier": "UPS",
"created_at": "2015-03-18T15:48:43Z",
"est_delivery_date": "2014-08-27T00:00:00Z",
"id": "trk_qufcxYmC",
"mode": "test",
"object": "Tracker",
"shipment_id": null,
"signed_by": null,
"status": "out_for_delivery",
"tracking_code": "EZ3000000003",
"tracking_details": [
{
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"datetime": "2014-08-21T14:24:00Z",
"message": "BILLING INFORMATION RECEIVED",
"object": "TrackingDetail",
"status": "pre_transit",
"tracking_location": {
"api_key": "IAiiSCSBtBXPKiaVmcc1wQ",
"city": null,
"country": null,
"object": "TrackingLocation",
"state": null,
"zip": null
}
},
# Removed same data as above to make shorter
"updated_at": "2015-03-18T15:48:43Z",
"weight": 17.6
} is not JSON serializable
>>>
It looks like the nested JSON in "tracking_details
" is causing errors to be thrown, any help on how to convert the data into a JSON Object?
看起来“tracking_details”中的嵌套JSON会导致抛出错误,有关如何将数据转换为JSON对象的任何帮助?
3 个解决方案
#1
1
So the quickest way I have been able to solve this has beeb via jsonpickle.
因此,我能够通过jsonpickle解决这个问题的最快捷方式。
Example from jsonpickle:
jsonpickle的示例:
import jsonpickle
frozen = jsonpickle.encode(obj)
Use jsonpickle to recreate a Python object from a JSON string:
thawed = jsonpickle.decode(frozen)
Warning Loading a JSON string from an untrusted source represents a potential security vulnerability. jsonpickle makes no attempt to sanitize the input.
The new object has the same type and data, but essentially is now a copy of the original.
assert obj.name == thawed.name
If you will never need to load (regenerate the Python class from JSON), you can pass in the keyword unpicklable=False to prevent extra information from being added to JSON:
oneway = jsonpickle.encode(obj, unpicklable=False)
result = jsonpickle.decode(oneway)
assert obj.name == result['name'] == 'Awesome'
Applied to this situation:
适用于这种情况:
>>>tracker_encode = jsonpickle.encode(tracker, unpicklable=False)
>>>tracker_decoded= jsonpickle.decode(tracker_encode)
>>> print type(tracker_decoded)
<type 'dict'>
>>> for x in tracker_decoded:
... print x
...
status
object
weight
tracking_details
shipment_id
created_at
_immutable_values
_transient_values
updated_at
_unsaved_values
tracking_code
carrier
mode
_values
est_delivery_date
_retrieve_params
api_key
id
signed_by
This encoded the entire output to a dictionary that I am then able to convert to json using the return JsonResponse({"tracking":tracking_decoded, "url":request.get_full_path})
这将整个输出编码为一个字典,然后我可以使用返回JsonResponse({“tracking”:tracking_decoded,“url”:request.get_full_path})将其转换为json。
Result using Postman:
使用Postman的结果:
#2
0
I think you need a Serializer!
我想你需要一个Serializer!
Check marshmallow at http://marshmallow.readthedocs.org !
检查http://marshmallow.readthedocs.org上的棉花糖!
I've been using this to JSON serialize my objects!
我一直用它来JSON序列化我的对象!
You will need to write something like:
你需要写一些类似的东西:
SomeObjectSerializer(Schema):
class Meta:
fields = ('api_key', 'id', 'someotherattributes')
and then when you want to serialize your objects just call:
然后当你想要序列化你的对象时,只需调用:
obj = Model(**args)
SomeObjectSerializer(obj).data
and this should be giving you a JSON serialized output
这应该是给你一个JSON序列化输出
#3
0
From the source, you can call tracker.to_dict()
从源代码,您可以调用tracker.to_dict()
The to_dict method is available on all EasyPost objects in the client.
to_dict方法可用于客户端中的所有EasyPost对象。
#1
1
So the quickest way I have been able to solve this has beeb via jsonpickle.
因此,我能够通过jsonpickle解决这个问题的最快捷方式。
Example from jsonpickle:
jsonpickle的示例:
import jsonpickle
frozen = jsonpickle.encode(obj)
Use jsonpickle to recreate a Python object from a JSON string:
thawed = jsonpickle.decode(frozen)
Warning Loading a JSON string from an untrusted source represents a potential security vulnerability. jsonpickle makes no attempt to sanitize the input.
The new object has the same type and data, but essentially is now a copy of the original.
assert obj.name == thawed.name
If you will never need to load (regenerate the Python class from JSON), you can pass in the keyword unpicklable=False to prevent extra information from being added to JSON:
oneway = jsonpickle.encode(obj, unpicklable=False)
result = jsonpickle.decode(oneway)
assert obj.name == result['name'] == 'Awesome'
Applied to this situation:
适用于这种情况:
>>>tracker_encode = jsonpickle.encode(tracker, unpicklable=False)
>>>tracker_decoded= jsonpickle.decode(tracker_encode)
>>> print type(tracker_decoded)
<type 'dict'>
>>> for x in tracker_decoded:
... print x
...
status
object
weight
tracking_details
shipment_id
created_at
_immutable_values
_transient_values
updated_at
_unsaved_values
tracking_code
carrier
mode
_values
est_delivery_date
_retrieve_params
api_key
id
signed_by
This encoded the entire output to a dictionary that I am then able to convert to json using the return JsonResponse({"tracking":tracking_decoded, "url":request.get_full_path})
这将整个输出编码为一个字典,然后我可以使用返回JsonResponse({“tracking”:tracking_decoded,“url”:request.get_full_path})将其转换为json。
Result using Postman:
使用Postman的结果:
#2
0
I think you need a Serializer!
我想你需要一个Serializer!
Check marshmallow at http://marshmallow.readthedocs.org !
检查http://marshmallow.readthedocs.org上的棉花糖!
I've been using this to JSON serialize my objects!
我一直用它来JSON序列化我的对象!
You will need to write something like:
你需要写一些类似的东西:
SomeObjectSerializer(Schema):
class Meta:
fields = ('api_key', 'id', 'someotherattributes')
and then when you want to serialize your objects just call:
然后当你想要序列化你的对象时,只需调用:
obj = Model(**args)
SomeObjectSerializer(obj).data
and this should be giving you a JSON serialized output
这应该是给你一个JSON序列化输出
#3
0
From the source, you can call tracker.to_dict()
从源代码,您可以调用tracker.to_dict()
The to_dict method is available on all EasyPost objects in the client.
to_dict方法可用于客户端中的所有EasyPost对象。