2

私は2つのモデルを持っています:

class SomeActivity(models.Model):
    name = models.ChartField(max_length=100)

class SomeStatus(models.Model):
    name = models.CharField(max_length=100)
    status = models.IntegerField(choises=STATUS_CHOISES)
    some_activity = models.ForeignKey(SomeActivity, related_name='statuses')

アクティビティの最後に作成されたステータスが現在のステータスです。それを取得するには、次のコードを使用します。

try:
    last_status = some_activity.statuses.latest('id')
except:
    last_status = None

Activitiesしかし、問題は、last_status一致するすべてのものを返すクエリを作成したい場合ですstatus__in=[1, 2]

4

1 に答える 1

2

このソリューションは少しねじれていますが、うまくいくと思います:

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))
  1. Django は、ルックアップ後にqs,qs.values()またはqs.values_list()が使用されると、サブクエリを自動的に生成します。__inしたがって、クエリセットを w/ でラップする必要はありませんlist()(不要な評価と不要な中間 SQL も導入されます) またはflat=True内部に書き込む必要はありません。qs.values_list()
  2. statuses__id__in内部のルックアップはactivitiesすでにテーブル結合を導入しているため、結合を利用するにはstatus__inからstatus_satisfied_idsに移動することをおactivities勧めします。そうしないと、status_satisfied_ids追加の選択が導入されます。

または、PostgreSQL の Window 関数を使用して、ランク付けされた位置で直接フィルタリングすることもできます。

于 2013-02-17T16:56:57.033 に答える