Django: "TypeError: []不能序列化为JSON" 为什么?
这个错误是怎么出现的呢?我输入了这个:
def json(self):
return json.dumps(
{
'items': self.items
}
)
结果却出现了那个错误(因为self.items是一个空的查询集(Django))
但是接下来,
def json(self):
return json.dumps(
{
'items': [] # Pass in empty list to prove that the error was idiotic.
}
)
却正常工作了(这至少证明了这个错误信息没什么用)
这是因为查询集定义了repr()方法,当它为空的时候返回'[]'这样的字符串,还是其他什么奇怪的原因吗?
3 个回答
4
正如Vinay所提到的,即使你把数据转换成列表,序列化(把数据转换成可以存储或传输的格式)通常还是会失败。对我来说,序列化在处理日期时间字段(datetime.datetime
对象)时经常出问题,即使我请求一个像列表一样的ValuesQuerySet
(通过.values()
获取)。我找到的解决办法是用简单的列表推导式。
json.dumps([str(obj) for obj in Model.objects.values()]);
在你的情况下,可以这样做:
return json.dumps({k: str(v) for k, v in self.__dict__.items()})
这里的str
函数真是救了我。还有repr
这个内置函数,如果你需要在序列化时获取对象类型的信息,它也可能会很有用。
6
这真让人头疼。Django的序列化功能对所有不是查询集的东西都很挑剔,而json.dumps又对Django的ORM支持的对象感到不满。
>>> from cluster.models import Account
>>> import json
>>> json.dumps(Account.objects.all()[0])
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 201, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 264, in iterencode
return _iterencode(o, 0)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 178, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Account: 9de5-2653-000d-81a3 => foo@bar.net> is not JSON serializable
对比一下
>>> serializers.serialize("json", [clusters])
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/serializers/__init__.py", line 91, in serialize
s.serialize(queryset, **options)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/serializers/base.py", line 41, in serialize
for field in obj._meta.local_fields:
AttributeError: 'QuerySet' object has no attribute '_meta'
60
查询集(Querysets)默认是不能直接转换成可存储格式的。如果你尝试用 list(self.items)
而不是直接用 self.items
,这样做应该没问题,只要这些项目本身是可以转换成JSON格式的。
更新:即使查询集不是空的,它也会抛出一个异常。不过我觉得这不会被认为是Django的一个bug,当然你可以试试;最简单的解决办法就是用 list(qs)
强制转换,就像我之前说的那样。