Wie konvertiere ich ein Django QuerySet in eine Liste von Diktaten?

122

Wie kann ich ein Django QuerySet in eine Liste von Diktaten konvertieren? Ich habe keine Antwort darauf gefunden und frage mich, ob mir eine allgemeine Hilfsfunktion fehlt, die jeder verwendet.

Mridang Agarwalla
quelle

Antworten:

176

Verwenden Sie die .values()Methode:

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

Hinweis: Das Ergebnis ist ein Ergebnis, QuerySetdas sich meistens wie eine Liste verhält, aber eigentlich keine Instanz von ist list. Verwenden list(Blog.objects.values(…))Sie diese Option, wenn Sie wirklich eine Instanz von benötigen list.

David Wolever
quelle
7
Ja, Sie geben an, welche Felder Sie zurückgeben möchten values(), indem Sie sie als Argumente übergeben. Seien Sie auch vorsichtig, obwohl es so aussieht, als ob Werte eine Liste von Diktaten zurückgeben, die tatsächlich eine <class 'django.db.models.query.ValuesQuerySet'>und keine Liste sind.
dm03514
10
Dies gibt jedoch keine Liste zurück
Astreltsov
Außerdem können Sie die Ergebnisse von Instanzmethoden Ihres Objekts values()nicht abrufen. Ich weiß nicht, ob es eine gute Methode gibt, um dasselbe zu tun, values()aber auch, um die Instanzmethoden aufzurufen.
Asara
34

Die .values()Methode gibt Ihnen ein Ergebnis vom Typ zurück, ValuesQuerySetdas in den meisten Fällen normalerweise benötigt wird.

Wenn Sie möchten, können Sie ValuesQuerySetmithilfe des Python-Listenverständnisses, wie im folgenden Beispiel dargestellt, eine native Python-Liste erstellen.

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

Ich finde die oben hilft , wenn Sie Unit - Tests und Notwendigkeit, assert schreiben , dass der erwartete Rückgabewert einer Funktion , um den tatsächlichen Rückgabewert übereinstimmt, wobei in diesem Fall beide expected_resultund actual_resultmuß vom gleichen Typ (zB Wörterbuch).

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result
Arthur Rimbun
quelle
17
Oder Sie können die Konvertierung in eine Liste mit diesem vereinfachenlist(result)
Adiyat Mubarak
12

Wenn Sie aus irgendeinem Grund native Datentypen benötigen (z. B. JSON-Serialisierung), ist dies meine schnelle und schmutzige Methode:

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

Wie Sie sehen können, ist das Erstellen des Diktats in der Liste nicht wirklich trocken. Wenn also jemand einen besseren Weg kennt ...

Semmel
quelle
Ich habe es anscheinend zum Laufen gebracht data = list( blogs )und dann json.dumps( data ). Ein Array enthält eine Reihe von Objekten auf der Javascript-Seite, ohne dass eine Analyse erforderlich ist.
Arthur Tarasov
3

Sie definieren nicht genau, wie die Wörterbücher aussehen sollen, aber höchstwahrscheinlich beziehen Sie sich darauf QuerySet.values(). Aus der offiziellen Django-Dokumentation :

Rückgabe a ValuesQuerySet- Eine QuerySetUnterklasse, die Wörterbücher zurückgibt, wenn sie als iterierbare Objekte und nicht als Modellinstanzobjekte verwendet werden.

Jedes dieser Wörterbücher stellt ein Objekt dar, wobei die Schlüssel den Attributnamen der Modellobjekte entsprechen.

Bernhard Vallant
quelle
2

Geben Sie Cast to List ein

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

    json.dumps(list(job_reports))
Saurabh Chandra Patel
quelle
1

Sie können die values()Methode für das Diktat verwenden, das Sie aus dem Django-Modellfeld erhalten haben, für das Sie die Abfragen durchführen, und dann können Sie einfach über einen Indexwert auf jedes Feld zugreifen.

Nennen Sie es so -

myList = dictOfSomeData.values()
itemNumberThree = myList[2] #If there's a value in that index off course...
Ido Magor
quelle
1

Sie benötigen DjangoJSONEncoderund listum dies Querysetzu erreichen json, ref: Python JSON serialisiert ein Dezimalobjekt

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


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

Einfach gesagt list(yourQuerySet).

Miguel de Matos
quelle
2
Dies gibt Ihnen eine Liste von Objekten, keine Liste von Diktaten.
Flimm
0

Sie können eine Funktion mit model_to_dict wie folgt definieren:

def queryset_to_dict(qs,fields=None, exclude=None):
    my_array=[]
    for x in qs:
        my_array.append(model_to_dict(x,fields=fields,exclude=exclude))
    return my_array
ABN
quelle