35 votes

Django: "TypeError: [] n'est pas JSON serializable" Pourquoi?

Comment cela se peut-il que cette erreur a été soulevée? J'ai participé:

def json(self):
    return json.dumps(
        {
            'items': self.items
        }
    )

et a obtenu cette erreur (car auto.articles était vide queryset (Django)

mais alors,

def json(self):
    return json.dumps(
        {
            'items': []  # Pass in empty list to prove that the error was idiotic.
        }
    )

a bien fonctionné (ce qui prouve que le message d'erreur est sans valeur)

Est-ce parce que le queryset définit repr() et renvoie '[]' comme un string quand elle est vide ou quelque chose de ridicule comme ça?

59voto

Vinay Sajip Points 41286

Querysets ne sont pas sérialisables out-of-the-box. Si vous essayez list(self.items) au lieu de simplement en self.items, qui devrait fonctionner aussi longtemps que les éléments eux-mêmes sont JSON-sérialisable.

Mise à jour: Il déclenche une exception, même si elle n'est pas vide. Je ne pense pas que ça va être accepté comme Django bug, même si bien sûr, vous pouvez essayer; la réponse la plus simple est de forcer l'évaluation à l'aide de list(qs), comme je l'ai déjà dit.

6voto

Ted Dunning Points 1043

C'est très frustrant. De Django reinhardt, la sérialisation se plaint de tout ce qui n'est pas une requête définie et json.décharges se plaint d'objets à partir de l'ORM de Django soutien.

>>> 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

Rapport

>>> 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'

4voto

hobs Points 3020

Comme Vinay souligné, même si vous lancez une liste, la sérialisation souvent ne fonctionne toujours pas. Pour moi, la sérialisation échoue sur DateTimeField éléments (datetime.datetime des objets), même si je demande un ValuesQuerySet (sous forme de liste) avec .values(). La solution pour moi a été une simple compréhension.

json.dumps([str(obj) for obj in Model.objects.values()]);

Dans votre cas, ce serait

return json.dumps({k: str(v) for k, v in self.__dict__.items()})

La magie de l' str sauve la journée. L' repr intégré peut également être utile si vous avez besoin d'un objet de type information dans votre sérialisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X