4

Meetup次の定義を持つ Django ORM モデルがあるとします。

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

単一のクエリを使用して、各言語の最新イベントの言語、スピーカー、および日付を取得したいと考えています。

>>> Meetup.objects.create(language='python', speaker='mike')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='python', speaker='ryan')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node', speaker='noah')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node', speaker='shawn')
<Meetup: Meetup object>
>>> Meetup.objects.values("language").annotate(latest_date=models.Max("date")).values("language", "speaker", "latest_date")
[
    {'speaker': u'mike', 'language': u'python', 'latest_date': ...}, 
    {'speaker': u'ryan', 'language': u'python', 'latest_date': ...}, 
    {'speaker': u'noah', 'language': u'node', 'latest_date': ...}, 
    {'speaker': u'shawn', 'language': u'node', 'latest_date': ...}, 
]

ああ!最新のイベントを取得していますが、グループ化が間違っています!

GROUP BYへの道が必要なようですがlanguageSELECT別のフィールドのセットですか?


更新- この種のクエリは、SQL で表現するのがかなり簡単なようです。

SELECT language, speaker, MAX(date)
FROM app_meetup
GROUP BY language;

Django を使わずにこれを行う方法が欲しいのraw()ですが、可能ですか?

更新 2 - 多くの検索の後、SO に同様の質問があるようです:

更新 3 - 最後に、@danihp の助けを借りて、2 つのクエリを実行するのが最善のようです。私は次のアプローチを使用しました:

# Abuse the fact that the latest Meetup always has a higher PK to build
# a ValuesList of the latest Meetups grouped by "language".
latest_meetup_pks = (Meetup.objects.values("language")
                                   .annotate(latest_pk=Max("pk"))
                                   .values_list("latest_pk", flat=True))

# Use a second query to grab those latest Meetups!
Meetup.objects.filter(pk__in=latest_meetup_pks)

この質問は、私の前の質問のフォローアップです。

Django ORM - グループの最新レコードを取得する

4

1 に答える 1