[python] Requête Django qui obtient les objets les plus récents de différentes catégories


Answers

Si vous utilisez PostGreSQL, vous pouvez utiliser l'interface de Django pour DISTINCT ON :

recent_cakes = Cake.objects.order_by('bakery__id', '-baked_at').distinct('bakery__id')

Comme le disent les docs , vous devez order by les mêmes champs que vous distinct on . Comme Simon l'a souligné ci-dessous, si vous voulez faire un tri supplémentaire, vous devrez le faire dans Python-space.

Question

J'ai deux modèles A et B Tous B objets B ont une clé étrangère à un objet A Étant donné un ensemble d'objets A , est-il possible d'utiliser l'ORM pour obtenir un ensemble d'objets B contenant l'objet le plus récent créé pour chaque objet A

Voici un exemple simplifié:

Class Bakery(models.Model):
    town = models.CharField()

Class Cake(models.Model):
    bakery = models.ForeignKey(Bakery)
    baked_at = models.DateTimeField()

Donc, je cherche une requête qui renvoie le gâteau le plus récent cuit dans chaque boulangerie à Anytown, États-Unis.




Cela devrait faire le travail:

from django.db.models import Max
Bakery.objects.annotate(Max('cake__baked_at'))



Cake.objects.filter(bakery__town="Anytown").order_by("-created_at")[:1]

Je n'ai pas construit les modèles de mon côté, mais en théorie cela devrait fonctionner. En panne:

  • Cake.objects.filter(bakery__town="Anytown") Devrait retourner tous les gâteaux qui appartiennent à "Anytown", en supposant que le pays ne fait pas partie de la chaîne. Les doubles soulignements entre la bakery et la town nous permettent d'accéder à la propriété town de la bakery .
  • .order_by("-created_at") ordonne les résultats par date de création, le plus récent en premier (notez le signe - (moins) dans "-created_at" .Sans le signe moins, ils seront triés du plus ancien au plus récent.
  • [:1] à la fin retournera seulement le 1er élément de la liste qui est retourné (qui serait une liste de gâteaux d'Anytown, triés par les plus récents en premier).

Note: Cette réponse est pour Django 1.11. Cette réponse a été modifiée à partir des requêtes présentées ici dans Django 1.11 Docs .




Related