82 votes

Requête Django qui récupère les objets les plus récents de différentes catégories

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

Voici un exemple simplifié :

class Bakery(models.Model):
    town = models.CharField(max_length=255)

class Cake(models.Model):
    bakery = models.ForeignKey(Bakery, on_delete=models.CASCADE)
    baked_at = models.DateTimeField()

Je cherche donc une requête qui renvoie le gâteau le plus récent fait dans chaque boulangerie de Anytown, aux États-Unis.

7 votes

J'aimerais bien voir ça aussi :-)

0voto

twknab Points 669
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. Cassé :

  • 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. Le double soulignement entre bakery y town nous permettent d'accéder au town propriété de bakery .
  • .order_by("-created_at") classera les résultats en fonction de leur date de création, les plus récents en premier (notez l'indication de la date de création). - (moins) dans "-created_at" . Sans le signe moins, ils seraient classés du plus ancien au plus récent.
  • [:1] à la fin ne renverra que le 1er élément de la liste qui est retournée (qui serait une liste de gâteaux de Anytown, triée par le plus récent en premier).

Remarque : cette réponse concerne Django 1.11. Cette réponse a été modifiée à partir des Requêtes présentées ici dans la documentation de Django 1.11 .

0voto

Nguyen Anh Vu Points 26

@Tomasz Zieliński solution ci-dessus a résolu votre problème mais pas le mien, car je dois encore filtrer le Cake. Voici donc ma solution

from django.db.models import Q, Max

hottest_yellow_round_cake = Max('cake__baked_at', filter=Q(cake__color='yellow', cake__shape='round'))

bakeries = Bakery.objects.filter(town='Chicago').annotate(
    hottest_cake_baked_at=hottest_yellow_round_cake
)

hottest_cakes = Cake.objects.filter(
    baked_at__in=[b.hottest_cake_baked_at for b in bakeries]
)

Avec cette approche, vous pouvez également mettre en œuvre d'autres éléments tels que le filtrage, la commande et la pagination pour les gâteaux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X