TypeError: <object> is not JSON serializable

TypeError: <object> is not JSON serializable

我试图在 Django 中使用 json.dumps() 将对象编码为 json,但是当我传入 python 对象时,它会引发此错误。

TypeError: <OrgInvite: OrgInvite object> is not JSON serializable

我假设即使 JSON 只能对某些数据类型进行编码,但其中一种数据类型是对象。我在 Stack Overflow 上阅读了另一个问题,解决这个问题的一个好方法是使用 .__dict__ 从对象中创建一个字典我试过了,它说我的新字典中的一个键,_state 不是可序列化。我不确定这个 _state 键是从哪里来的,想知道有没有办法把我的对象转换成没有那个额外字段的字典,这样我就可以把它编码成 JSON ?

型号:

class OrgInvite(models.Model):
    token = models.CharField(max_length=16, unique=True, null=False)
    account_id = models.ForeignKey(Account, on_delete=models.CASCADE, null=False)
    org_id = models.ForeignKey(Org, on_delete=models.CASCADE, null=False)
    used = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    name = models.CharField(max_length=70)
    email = models.CharField(max_length=255)

查看:

def get_invite(token):
    if not token:
        raise Exception("Invitation token is not specified")

    invitation = OrgInvite.objects.get(token=token)
    if not invitation:
        raise Exception("Invitation token is invalid.")

    return invitation

def invite_accept_redirect(token):
    # """ -Redirects to the accept invite frontend view with pre-fetched data. """

    try:
        invite = get_invite(token)
        if not invite:
            raise Exception("Invitation token is invalid")
        if invite.used:
            invite = {'used': True}
    except:
        invite = {'invalid': True}
        raise Exception("Resource not found.")

    base = "home/accept"

    url = '{}/{}?data={}'.format(base, token, urllib.quote_plus(json.dumps(invite.__dict__)))

    return redirect(url)

控制台:

>>> oi = OrgInvite.objects.get(token=100) 
>>> oi
<OrgInvite: OrgInvite object>
>>> oix = oi.__dict__
>>> oix
{'used': False, 'name': u'', '_state': <django.db.models.base.ModelState object at 0x10377a610>, 'email': u'', 'token': u'100', 'org_id_id': 101, 'account_id_id': 301, 'is_admin': False, 'id': 1}
>>> json.dumps(oix)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 244, in dumps
    return _default_encoder.encode(obj)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <django.db.models.base.ModelState object at 0x10377a610> is not JSON serializable

object 不是这些类型之一。字典、列表(可能是元组)、浮点数、字符串、整数、布尔值和 None 我 相信 是 Python 可以序列化为 [=24= 的类型] 原生。

不过,看起来 Django has some built-in serializers 可能适合您。

我猜

from django.core import serializers
data = serializers.serialize("json", OrgInvite.objects.filter(token=100))

应该适合你

如果您执行 invite.__dict__,它将为您提供与一个 invite 对象相关的所有数据的字典。但是,dict 的值不一定是原始类型,也可以是对象(ModelState 只是其中之一)。序列化不仅因为 json 不接受 python 对象而不起作用,而且您还可以序列化大量未使用的元数据。

查看 json official website to see what data types are json serializable. The fix would be either using django model serializer,或手动创建符合 json 格式的字典。

__dict__ 给出了实例的所有属性,但您不想要所有这些额外的包袱——出于序列化的目的,您只对字段感兴趣。

您的模型不包含任何特殊内容,因此内置辅助函数 model_to_dict 应该足以满足您的需求:

import json
from django.forms.models import model_to_dict

oi = OrgInvite.objects.get(token=100) 
oi_dict = model_to_dict(oi)
oi_serialized = json.dumps(oi_dict)

您的示例很简单,仅包含 CharFieldBooleanFieldForeignKey,所有这些我们都可以简单地转储到 json

对于更复杂的模型,您可以考虑自己编写 serializer. In this case, I recommend using the popular django-rest-framework,它会为您完成所有工作。

from rest_framework import serializers

class OrgInviteSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrgInvite
        fields = '__all__'