TypeError:Python对象不是JSON可序列化的 [英] TypeError: Python object is not JSON serializable
问题描述
我试图在Django中使用json.dumps()
将对象编码为json,但是当我传递python对象时,会引发此错误.
I am trying to encode an object into json using json.dumps()
in Django, however when I pass in a python object, it raises this error.
TypeError: <OrgInvite: OrgInvite object> is not JSON serializable
我假设即使JSON只能编码某些数据类型,但这些数据类型之一是对象.我读了另一个关于Stack Overflow的问题,一种解决此问题的好方法是使用我尝试过的.__dict__
在对象之外创建一个字典,这是说新字典中的键之一_state无法序列化.我不确定这个_state键的来源,并且想知道是否有一种方法可以将我的对象转换成没有额外字段的字典,因此我可以将其编码为JSON吗?
I was under the assumption that even though JSON can only encode certain data types, one of those data types were objects. I read another question on Stack Overflow that a good way to get around this is by creating a dictionary out of the object using .__dict__
I tried this and it is saying that one of the keys in my new dictionary, _state is not serializable. I am not sure where this _state key came from, and was wondering is there a way to convert my object into a dictionary without that extra field, so I can encode it into 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
推荐答案
__dict__
给出了实例的所有属性,但是您不希望所有这些额外的负担-出于序列化的目的,您只感兴趣在田野里.
The __dict__
gives all the attributes of the instance, but you don't want all that extra baggage - for the purposes of serialization, you are only interested in the fields.
您的模型不包含任何特殊内容,因此内置的帮助器功能model_to_dict
应该足以满足您的需求:
Your model does not contain anything special so the built-in helper function model_to_dict
should be enough for your needs:
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)
您的示例很简单,仅包含CharField
,BooleanField
和ForeignKey
,我们可以将它们全部转储到json
.
Your example was simple, only containing CharField
, BooleanField
, and ForeignKey
all of which we can dump to json
trivially.
对于更复杂的模型,您可以考虑编写自己的 serializer .在这种情况下,我建议使用流行的 django-rest-framework 来完成所有工作你.
For more complicated models, you might consider writing your own serializer. In this case, I recommend using the popular django-rest-framework which does all the work for you.
from rest_framework import serializers
class OrgInviteSerializer(serializers.ModelSerializer):
class Meta:
model = OrgInvite
fields = '__all__'
这篇关于TypeError:Python对象不是JSON可序列化的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!