Django ORM-получить последнюю запись для группы

представьте, что у нас есть модель Django ORM Meetup со следующим определением:

class Meetup(models.Model):
    language = models.CharField()
    date = models.DateField(auto_now=True)

Я хотел бы получить последнюю встречу для каждого языка.

казалось бы, вы могли бы использовать Django Агрегаты чтобы сделать этот поиск легким:

Meetup.objects.annotate(latest_date=Max("date")).values("language", "latest_date")

на мой взгляд, это должно принести "последнее" собрание для каждого языка. Но это не так:

>>> Meetup.objects.create(language='python')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='python')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node')
<Meetup: Meetup object>
>>> Meetup.objects.annotate(latest_date=Max("date")).values("language", "latest_date").count()
4

Я ожидал получить только два последних Python и Node митапы!

как я могу создать запрос, который будет получать только последние встречи для каждого языка?

PS. Я использую MySQL в качестве бэкэнда.

1 ответов


положить values п. перед annotate.

С агрегация документов:

если предложение values () предшествует предложению annotate (), аннотация будет вычислена с использованием группировки, описанной предложением values ().

однако, если предложение annotate() предшествует предложению values (), аннотации будут сгенерированы по всему набору запросов. В этом случае предложение values() ограничивает только поля, которые генерируется на выходе.

Так что это должно сделать это:

Meetup.objects.values('language').annotate(latest_date=Max('date'))