190 votes

Comment convertir un Django QuerySet en liste de dicts ?

Comment convertir un Django QuerySet en une liste de dicts ? Je n'ai pas trouvé de réponse à cette question et je me demande donc si je ne manque pas une sorte de fonction d'aide commune que tout le monde utilise.

290voto

David Wolever Points 34304

Utilisez le .values() méthode :

>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

Remarque : le résultat est un QuerySet qui se comporte principalement comme une liste, mais qui n'est pas réellement une instance de list . Utilisez list(Blog.objects.values(…)) si vous avez vraiment besoin d'une instance de list .

7 votes

Oui vous spécifiez les champs que vous voulez values() à retourner en les passant comme arguments. Faites également attention, bien que values semble retourner une liste de dicts, il s'agit en fait de <class 'django.db.models.query.ValuesQuerySet'> et non une liste.

20 votes

Ceci ne retourne pas réellement une liste

0 votes

Aussi, vous ne pouvez pas obtenir les résultats des méthodes d'instance de votre objet avec values() je ne sais pas s'il existe une bonne méthode pour faire de même que values() mais aussi avec l'appel des méthodes d'instance !

38voto

Arthur Rimbun Points 2993

En .values() vous renverra un résultat de type ValuesQuerySet ce qui est généralement ce dont vous avez besoin dans la plupart des cas.

Mais si vous le souhaitez, vous pouvez tourner ValuesQuerySet en une liste native Python en utilisant la compréhension de liste Python comme illustré dans l'exemple ci-dessous.

result = Blog.objects.values()             # return ValuesQuerySet object
list_result = [entry for entry in result]  # converts ValuesQuerySet into Python list
return list_result

Je trouve que ce qui précède est utile si vous écrivez des tests unitaires et que vous avez besoin d'affirmer que la valeur de retour attendue d'une fonction correspond à la valeur de retour réelle. expected_result y actual_result doivent être du même type (par exemple, un dictionnaire).

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result

21voto

Semmel Points 157

Si vous avez besoin de types de données natifs pour une raison ou une autre (par exemple, la sérialisation JSON), voici ma façon rapide et sale de le faire :

data = [{'id': blog.pk, 'name': blog.name} for blog in blogs]

Comme vous pouvez le constater, la construction du dict dans la liste n'est pas vraiment DRY, donc si quelqu'un connaît un meilleur moyen ...

0 votes

Je semble avoir réussi à le faire fonctionner avec data = list( blogs ) et ensuite json.dumps( data ) . Un tableau donne un ensemble d'objets du côté du javascript, sans qu'il soit nécessaire de l'analyser.

8voto

Type Cast to List

    job_reports = JobReport.objects.filter(job_id=job_id, status=1).values('id', 'name')

    json.dumps(list(job_reports))

5voto

gaozhidf Points 773

Vous devez DjangoJSONEncoder y list pour faire de votre Queryset a json , réf : Python JSON sérialise un objet Decimal

import json
from django.core.serializers.json import DjangoJSONEncoder

blog = Blog.objects.all().values()
json.dumps(list(blog), cls=DjangoJSONEncoder)

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