このソリューションは少しねじれていますが、うまくいくと思います:
from django.db.models import Max
max_status_ids = SomeActivity.objects.filter(statuses__isnull=False).annotate(
last_status_id=Max('statuses__id')
).values_list('last_status_id', flat=True)
status_satisfied_ids = SomeStatus.objects.filter(id__in=list(max_status_ids),
status__in=[1, 2]).values_list('id', flat=True)
activities = SomeActivity.objects.filter(statuses__id__in=list(
status_satisfied_ids))
より良い解決策があることを願っています。
アップデート
試す
max_status_ids = SomeActivity.objects.annotate(last_status_id=Max('statuses')
).values('last_status_id')
activities = SomeActivity.objects.filter(statuses__in=max_status_ids,
statuses__status__in=(1,2))
- Django は、ルックアップ後に
qs,qs.values()またはqs.values_list()が使用されると、サブクエリを自動的に生成します。__inしたがって、クエリセットを w/ でラップする必要はありませんlist()(不要な評価と不要な中間 SQL も導入されます) またはflat=True内部に書き込む必要はありません。qs.values_list()
statuses__id__in内部のルックアップはactivitiesすでにテーブル結合を導入しているため、結合を利用するにはstatus__inからstatus_satisfied_idsに移動することをおactivities勧めします。そうしないと、status_satisfied_ids追加の選択が導入されます。
または、PostgreSQL の Window 関数を使用して、ランク付けされた位置で直接フィルタリングすることもできます。