Django:“TypeError:[] 不是 JSON 可序列化的”为啥?
Posted
技术标签:
【中文标题】Django:“TypeError:[] 不是 JSON 可序列化的”为啥?【英文标题】:Django: "TypeError: [] is not JSON serializable" Why?Django:“TypeError:[] 不是 JSON 可序列化的”为什么? 【发布时间】:2011-01-15 15:01:58 【问题描述】:怎么会引发这个错误?我输入了这个:
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() 并在它为空或类似荒谬的情况下将 '[]' 作为字符串返回?
【问题讨论】:
你为什么要定义一个与你正在使用的模块同名的函数? @gnibbler 这不是一个函数。这是一种方法,我将它用作@property(在我的示例中没有包含它)。 我喜欢回顾我的自鸣得意,...the error was idiotic.
【参考方案1】:
查询集不是开箱即用的可序列化。如果您尝试使用 list(self.items)
而不仅仅是 self.items
,只要项目本身是 JSON 可序列化的,这应该可以工作。
更新:即使不为空也会引发异常。我不认为它会被接受为 Django 错误,尽管您当然可以尝试;正如我已经说过的,最简单的答案是使用list(qs)
强制评估。
【讨论】:
+1。这就是答案。您正在使用 list(queryset) 强制立即评估查询集。底层数据,以列表的形式,是可序列化的;查询集本身不是。 docs.djangoproject.com/en/dev/ref/models/querysets/#id1 好答案。谢谢。顺便说一句,这似乎是一个错误。我要开始买票了。 Django 的序列化器用于序列化 Django 查询集。如果它在为空时引发异常,那就是一个错误。 @orokusaki,这对我来说并不像一个错误。有时你想要对象。有时你想要字符串。 Django 让你选择。对于所有 Django 字段,这是一个更适合我的 Pythonic 替代方案:[str(obj) for obj in Model.objects.values()]
see below【参考方案2】:
这很令人沮丧。 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'
【讨论】:
【参考方案3】:正如 Vinay 指出的那样,即使您投射到列表中,序列化通常仍然会失败。对我来说,DateTimeField 元素(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
也可能会有所帮助。
【讨论】:
以上是关于Django:“TypeError:[] 不是 JSON 可序列化的”为啥?的主要内容,如果未能解决你的问题,请参考以下文章