Подтвердить что ты не робот

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.
        }
    )

работал нормально (что, по крайней мере, доказывает, что сообщение об ошибке бесполезно)

Это потому, что queryset определяет repr() и возвращает '[]' как строку, когда она пуста или что-то нелепое?

4b9b3361

Ответ 1

Querysets не могут быть сериализованы из коробки. Если вы попробуете list(self.items) вместо self.items, это должно работать до тех пор, пока сами элементы являются JSON-сериализуемыми.

Обновление:. Это приведет к возникновению исключения, даже если оно не пустое. Я не думаю, что это будет воспринято как ошибка Django, хотя, конечно, вы можете попробовать; самый простой ответ - принудительная оценка с использованием list(qs), как я уже сказал.

Ответ 2

Это очень неприятно. Сериализация Django жалуется на все, что не является набором запросов, и json.dumps жалуется на объекты из поддержки ORM Django.

>>> 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 => [email protected]> 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

Как отметил Винай, даже если вы включили в список, сериализация часто по-прежнему терпит неудачу. Для меня сериализация терпит неудачу в элементах DateTimeField (datetime.datetime objects), даже если я попрошу ValuesQuerySet (list-like) с .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 также может быть полезен, если вам нужна информация о типе объектов в вашей сериализации.