Django 1.7 a introduit les objets JsonResponse , que j'essaie d'utiliser pour renvoyer une liste de valeurs à ma demande ajax.
Je veux passer
>>> Genre.objects.values('name', 'color')
[{'color': '8a3700', 'name': 'rock'}, {'color': 'ffff00', 'name': 'pop'}, {'color': '8f8f00', 'name': 'electronic'}, {'color': '9e009e', 'name': 'chillout'}, {'color': 'ff8838', 'name': 'indie'}, {'color': '0aff0a', 'name': 'techno'}, {'color': 'c20000', 'name': "drum'n'bass"}, {'color': '0000d6', 'name': 'worldmusic'}, {'color': 'a800a8', 'name': 'classic'}, {'color': 'dbdb00', 'name': 'hiphop'}]
à un objet JsonResponse.
Cependant, mes tentatives échouent.
>>> JsonResponse({'foo': 'bar', 'blib': 'blab'}) # works
<Django.http.response.JsonResponse object at 0x7f53d28bbb00>
>>> JsonResponse(Genre.objects.values('name', 'color')) # doesn't work
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/marcel/Dokumente/Django/FlushFM/env/lib/python3.4/site-packages/Django/http/response.py", line 476, in __init__
raise TypeError('In order to allow non-dict objects to be '
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False
Cela est probablement dû à la structure différente des données de Genre.objects.values()
.
Comment cela pourrait-il être fait correctement?
[Éditer]
Avec safe=False
Je reçois
>>> JsonResponse(Genre.objects.values('name', 'color'), safe=False)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/marcel/Dokumente/Django/FlushFM/env/lib/python3.4/site-packages/Django/http/response.py", line 479, in __init__
data = json.dumps(data, cls=encoder)
File "/usr/lib/python3.4/json/__init__.py", line 237, in dumps
**kw).encode(obj)
File "/usr/lib/python3.4/json/encoder.py", line 192, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.4/json/encoder.py", line 250, in iterencode
return _iterencode(o, 0)
File "/home/marcel/Dokumente/Django/FlushFM/env/lib/python3.4/site-packages/Django/core/serializers/json.py", line 109, in default
return super(DjangoJSONEncoder, self).default(o)
File "/usr/lib/python3.4/json/encoder.py", line 173, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: [{'color': '8a3700', 'name': 'rock'}, {'color': 'ffff00', 'name': 'pop'}, {'color': '8f8f00', 'name': 'electronic'}, {'color': '9e009e', 'name': 'chillout'}, {'color': 'ff8838', 'name': 'indie'}, {'color': '0aff0a', 'name': 'techno'}, {'color': 'c20000', 'name': "drum'n'bass"}, {'color': '0000d6', 'name': 'worldmusic'}, {'color': 'a800a8', 'name': 'classic'}, {'color': 'dbdb00', 'name': 'hiphop'}] is not JSON serializable
Ce qui fonctionne est
>>> JsonResponse(list(Genre.objects.values('name', 'color')), safe=False)
<Django.http.response.JsonResponse object at 0x7f53d28bb9e8>
Mais n'y a-t-il pas une meilleure façon de générer un dict à partir d'un objet Model?
Pour référence future, .values()
renvoie un ValuesQuerySet
qui se comporte comme un itérable plein de dictionnaires, donc l'utilisation de list()
créera une nouvelle instance d'un list
avec tous les dictionnaires qu'il contient. Avec cela, vous pouvez créer un nouveau dict et le sérialiser.
response = JsonResponse(dict(genres=list(Genre.objects.values('name', 'color'))))
IIRC, il n'est pas sûr d'avoir un objet JSON qui a une liste en tant que root et c'est probablement pourquoi Django se plaint. Je n'ai pu trouver aucune référence à ce sujet maintenant pour fournir une source, désolé.