2009-06-02 7 views
6

Ich hole die letzten 5 Zeilen von einem Foo-Modell, das nach einem Datetime-Feld geordnet ist.django - Abfrage nach dem Schneiden neu sortieren

qs = Foo.objects.all()[:5] 

Im folgenden Schritt mag ich die queryset von einigen anderen Kriterien neu zu ordnen (eigentlich von dem gleichen Datetime-Feld in der entgegengesetzten Richtung). Neuordnung nach einer Scheibe ist jedoch nicht erlaubt. reverse() macht die erste Reihenfolge rückgängig und gibt mir einen anderen Abfragewert. Gibt es eine Möglichkeit, das zu erreichen, was ich möchte, ohne eine Liste aus dem Abfrage-Set zu erstellen und die Reihenfolge zu verwenden?

Antwort

10

Nein, es gibt keine Möglichkeit, das zu tun. order_by ist eine Operation für die Datenbank, aber wenn Sie einen Abfragesatz zerlegen, wird dieser ausgewertet und danach nicht mehr in die Datenbank zurückversetzt.

Klingt, als ob Sie die Lösung bereits kennen: Führen Sie reversed() auf der ausgewerteten qs.

qs = reversed(Foo.objects.all()[:5]) 
+0

So habe ich nichts verpasst. Vielen Dank. – shanyu

+0

Ich hatte das gleiche Problem und folgte Daniel Vorschlag, aber fand, dass ich Count-Methode für die Abfrage nicht verwenden konnte – thchand

+0

Kann nicht finden Sie einen Verweis auf umgekehrte() in Python-Dokumente, alle Links, die Sie bereitstellen können? –

13

order_by gibt Ihnen SQL-In-Datenbank-Bestellung. Sie benutzen das bereits und schneiden es dann auf. Zu diesem Zeitpunkt werden die Ergebnisse in den Speicher abgerufen. Wenn Sie ihre Reihenfolge ändern möchten, müssen Sie die In-Memory-Sortierung nach Python verwenden, nicht die ORM-Sortierung in der Datenbank.

In Ihrem Fall Daniel hat bereits die beste Lösung gegeben: da man einfach durch das gleiche Feld sortieren wollen, aber in der anderen Reihenfolge umgekehrt nur die Liste Sie haben:

qs = Foo.objects.all()[:5] 
objs = reversed(qs) 

Wenn Sie hatte wollte durch ein anderes Feld sortieren, mit einer benutzerdefinierten Schlüsselfunktion würden Sie dann die sortierte() Funktion:

qs = Foo.objects.all()[:5] 
objs = sorted(qs, key=lambda o: o.some_other_field) 
+0

Ja, ich weiß, dass order_by eine DB Bestellung ist. Aber ich habe es interessant gefunden, dass eine reverse() (die Methode queryset) nach dem Slice funktioniert, und dass es die Abfrage erneut ausführt, was zu unerwarteten Ergebnissen führt. – shanyu

+0

Wenn Sie Ergebnisse aus einem Abfrage-Set ziehen, ist es immer noch ein gültiges Abfrage-Set. Wenn Sie es ändern (z. B. indem Sie reverse() hinzufügen), wird es erneut ausgewertet. –

1

Späte Antwort, aber dies ist nur für mich:

import random 
sorted(queryset[:10], key=lambda x: random.random())