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.

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.


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

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


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.


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

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

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)


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.