Créer une fonction d'aide pour extraire en toute sécurité le « top » élément de n'importe quel jeu de requête. Je l'utilise partout dans mes propres applications Django.
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
Il utilise un peu d'un tour w/la slice operator to add a limit clause onto your SQL.
Maintenant, utilisez cette fonction où vous voulez obtenir l'élément 'haut' d'un ensemble de requêtes. Dans ce cas, vous voulez obtenir l'élément supérieur B pour une donnée A où les B sont classés par ordre décroissant pk, en tant que tel:
latest = top_or_none(B.objects.filter(a=my_a).order_by('-pk'))
Il y a aussi récemment ajouté la fonction « Max » dans Django Aggregation qui pourrait vous aider obtenir le maximum de PC, mais je n'aime pas cette solution dans ce cas, car il ajoute de la complexité.
P.S. Je n'aime pas vraiment utiliser le champ 'pk' pour ce type de requête, car certains SGBDR ne garantissent pas que les paquets séquentiels sont identiques à l'ordre de création logique. Si j'ai une table dont je sais que je vais devoir faire une requête de cette manière, j'ai habituellement ma propre colonne 'creation' datetime que je peux utiliser pour passer commande au lieu de pk.
Modifier basé sur le commentaire:
Si vous préférez utiliser queryset [0], vous pouvez modifier le 'top_or_none' fonction ainsi:
def top_or_none(queryset):
"""Safely pulls off the top element in a queryset"""
try:
return queryset[0]
except IndexError:
return None
Je n'ont pas proposé ce départ parce que j'étais sous l'impression que QuerySet [0] reculerait l'ensemble des résultats, puis prendrait le 0ème élément. Apparemment, Django ajoute un 'LIMIT 1' dans ce scénario, donc c'est une alternative sûre à ma version de découpage.
Edit 2
Bien sûr, vous pouvez également profiter de gestionnaire connexes de Django construire ici et construire le queryset par votre « A » objet, selon vos préférences:
latest = top_or_none(my_a.b_set.order_by('-pk'))
Quelle est la différence entre résultat = jeu de queues [0: 1] et résultat = jeu de queues [0]? – hekevintran
queryset [0: 1] renvoie une liste vide lorsqu'il n'y a pas d'éléments correspondants, tandis que queryset [0] lance une erreur IndexError. –
Merci pour la réponse! – hekevintran