eine Hilfsfunktion erstellen für sicher die ‚top‘ Extrahieren Element aus einem beliebigen Abfrage-Set. Ich nutze das überall in meinen eigenen Django-Apps.
def top_or_none(queryset):
"""Safely pulls off the top element in a queryset"""
# Extracts a single element collection w/ top item
result = queryset[0:1]
# Return that element or None if there weren't any matches
return result[0] if result else None
Dies verwendet ein bisschen einen Trick mit der slice operator to add a limit clause onto your SQL.
Verwenden Sie diese Funktion nun an einer beliebigen Stelle, an der Sie das oberste Element eines Abfrage-Sets abrufen müssen. In diesem Fall sollten Sie die Top-B-Punkt für einen bestimmten A erhalten, wo die B durch absteigend pk sortiert sind, als solche:
latest = top_or_none(B.objects.filter(a=my_a).order_by('-pk'))
Es gibt auch die kürzlich hinzugefügte ‚Max‘ Funktion in Django Aggregation, die Ihnen helfen könnten Holen Sie sich die maximale pk, aber ich mag diese Lösung in diesem Fall nicht, da es Komplexität hinzufügt.
P.S. Ich mag es nicht wirklich, für diese Art von Abfrage auf das 'pk'-Feld zu vertrauen, da einige RDBMS nicht garantieren, dass sequentielle pks mit der logischen Erstellungsreihenfolge identisch sind. Wenn ich eine Tabelle habe, von der ich weiß, dass ich sie auf diese Weise abfragen muss, habe ich normalerweise meine eigene "create" -Datetime-Spalte, mit der ich anstelle von pk bestellen kann.
bearbeiten basierend auf Kommentar:
Wenn Sie lieber queryset verwenden würde [0] können Sie die 'top_or_none' Funktion thusly ändern:
def top_or_none(queryset):
"""Safely pulls off the top element in a queryset"""
try:
return queryset[0]
except IndexError:
return None
ich dies zunächst nicht vorschlagen weil ich den Eindruck hatte, dass queryset [0] die gesamte Ergebnismenge zurückziehen würde, dann nehme ich das 0. Item. Anscheinend fügt Django auch in diesem Szenario eine 'LIMIT 1' hinzu, also ist es eine sichere Alternative zu meiner Slicing-Version.
Edit 2
Natürlich können Sie auch die Vorteile von Djangos verwandten Manager nehmen hier konstruieren und die queryset durch Ihre ‚A‘ Objekt bauen, je nach Wunsch:
latest = top_or_none(my_a.b_set.order_by('-pk'))
Was ist der Unterschied zwischen Ergebnis = Queryset [0: 1] und Ergebnis = Queryset [0]? – hekevintran
queryset [0: 1] gibt eine leere Liste zurück, wenn keine übereinstimmenden Elemente vorhanden sind, wohingegen queryset [0] einen IndexError auslöst. –
Danke für die Antwort! – hekevintran