将 Class 对象转换为 JSON Python - EasyPost - Django

Convert Class Object to JSON Python - EasyPost - Django

我正在通过 Python 2.7.9 在 Django 1.7 中构建一个 Json响应视图,用于跟踪通过 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}) 

当这不起作用时,我试图查看问题是否与 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" 是一个 class 对象

>>> print type(tracker)  
<class 'easypost.Tracker'>

尝试将 class 转换为字典:

>>> 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'

尝试转储到 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
>>> 

看起来“tracking_details”中的嵌套 JSON 导致抛出错误,关于如何将数据转换为 JSON 对象的任何帮助?

我认为你需要一个序列化程序!

http://marshmallow.readthedocs.org 查看棉花糖!

我一直在使用它 JSON 序列化我的对象!

你需要这样写:

SomeObjectSerializer(Schema):
    class Meta:
      fields = ('api_key', 'id', 'someotherattributes')

然后当你想序列化你的对象时,只需调用:

obj = Model(**args)
SomeObjectSerializer(obj).data

这应该会给你一个 JSON 序列化输出

所以我能够通过 jsonpickle.

解决这个问题的最快方法是 beeb

来自 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'

适用于这种情况:

>>>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

这将整个输出编码为字典,然后我可以使用 return JsonResponse({"tracking":tracking_decoded, "url":request.get_full_path})

将其转换为 json

使用Postman的结果:

the source开始,您可以调用tracker.to_dict()

to_dict() 方法可用于客户端中的所有 EasyPost 对象。

Example: tracker.to_dict().