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 可序列化的”为啥?的主要内容,如果未能解决你的问题,请参考以下文章

Django之路

Django系列

django 错误

mac电脑安装django ,运行django报错解决

Django 大神带你飞系列~走进Django

django的文档