Ich möchte die letzten 10 Instanzen eines Modells nehmen und diesen Code haben:
Model.objects.all().order_by('-id')[:10]
Stimmt es, dass zuerst alle Instanzen und dann nur 10 letzte Instanzen aufgenommen werden? Gibt es eine effektivere Methode?
Antworten:
Django-Abfragesätze sind faul. Das bedeutet, dass eine Abfrage nur dann in die Datenbank gelangt, wenn Sie speziell nach dem Ergebnis fragen.
Bis Sie das Ergebnis einer Abfrage drucken oder tatsächlich verwenden, können Sie ohne Datenbankzugriff weiter filtern.
Wie Sie unten sehen können, führt Ihr Code nur eine SQL-Abfrage aus, um nur die letzten 10 Elemente abzurufen.
quelle
Eigentlich denke ich, dass das
LIMIT 10
an die Datenbank ausgegeben wird, so dass das Schneiden nicht in Python, sondern in der Datenbank stattfinden würde.Weitere Informationen finden Sie unter Einschränken von Abfragesätzen .
quelle
Es sieht so aus, als ob die Lösung in der Frage nicht mehr mit Django 1.7 funktioniert und einen Fehler auslöst: "Eine Abfrage kann nicht neu angeordnet werden, sobald ein Slice erstellt wurde."
Gemäß der Dokumentation https://docs.djangoproject.com/de/dev/topics/db/queries/#limiting-querysets wertet das Erzwingen des "step" -Parameters der Python-Slice-Syntax die Abfrage aus. Es funktioniert so:
Trotzdem frage ich mich, ob das Limit in SQL- oder Python-Slices ausgeführt wird und das gesamte Ergebnisarray zurückgegeben wird. Es ist nicht gut, große Listen in den Anwendungsspeicher abzurufen.
quelle
Ja. Wenn Sie eine begrenzte Teilmenge von Objekten abrufen möchten, können Sie dies mit dem folgenden Code tun:
Beispiel:
Der Anfang 0 ist also optional
Der obige Code gibt die ersten 10 Instanzen zurück.
quelle
Als Ergänzung und Beobachtung zu den anderen nützlichen Antworten ist zu beachten, dass beim tatsächlichen
[:10]
Schneiden die ersten 10 Elemente der Liste zurückgegeben werden , nicht die letzten 10 ...Um die letzten 10 zu erhalten, sollten Sie
[-10:]
stattdessen (siehe hier ) tun . Auf diese Weise können Sie vermeiden, die Elementeorder_by('-id')
mit-
umzukehren.quelle
Product.objects.filter(~Q(price=0))[-5:]
verursacht mir den gleichen Fehler: "Negative Indizierung wird nicht unterstützt."