Django-Abfrage erhalten die letzten n Datensätze

70

Nehmen wir an, ich implementiere einen Nachrichtenstrom, sortiere Datensätze nach aufsteigender Reihenfolge der ID, jede Abrufanforderung möchte ich nur zulassen, dass die neuesten 10 Datensätze abgerufen werden.

Ich habe es versucht:

Messages.objects.filter(since=since)[:-10]

Und ich hatte den Fehler, dass die negative Indizierung nicht unterstützt wird.

Meine aktuelle Problemumgehung besteht darin, die ID in absteigender Reihenfolge zu sortieren und dann auszuführen:

Messages.objects.filter(since=since)[:10]

Dies erfordert jedoch, dass das Frontend die Reihenfolge erneut umkehrt.

Meine Frage ist, gibt es eine elegante Möglichkeit, dies zu tun?

James Lin
quelle

Antworten:

88

Sie können Ihr Abfrageset umgekehrt übergeben :

last_ten = Messages.objects.filter(since=since).order_by('-id')[:10]
last_ten_in_ascending_order = reversed(last_ten)
Robert Kajic
quelle
45

Oder verwenden Sie [::-1]anstelle von reversed:

last_ten = Messages.objects.filter(since=since).order_by('-id')[:10][::-1]
Omid Raha
quelle
3
Ich dachte nicht, dass eine negative Indizierung unterstützt wird?
Orangft
2
Es wird eine reguläre Liste, nicht länger ein Django-Abfragesatz, nach dem [:10]Schneiden
RubberDuckRabbit
Wenn Ihr Primärschlüssel UUID ist, funktioniert dies nicht, da order_by ('- id) die ID alphabetisch sortiert und die UUID immer zufällig ist.
Karan Kumar
8
+1, das hat mir geholfen. Ihre Lösung verwendet das Listenverständnis jedoch zweimal (zuerst auf 10 schneiden, dann umkehren). Sie können es als eine Operation tun - last_ten = Messages.objects.filter(since=since).order_by('-id')[:10:-1]. Ich habe es mit einer Standardliste zeitlich festgelegt und es ist 9x schneller.
Ron_g
24

Wenn Sie möchten, dass die letzten X-Datensätze in absteigender Reihenfolge nach ID sortiert werden , brauchen Sie diese seit dem Filter nicht mehr

last_ten = Messages.objects.all().order_by('-id')[:10]

Mit -id wird in absteigender Reihenfolge sortiert. Hoffe das war hilfreich !!

allsyed
quelle
3
Wie effizient ist diese Abfrage im Vergleich zur akzeptierten Antwort? Vielen Dank.
Fast ein Anfänger
1
Filter verwendet whereKlausel, während die obige Abfrage eine einfache Auswahl mit order byKlausel ist
allsyed