模型是这样的:
class Application(models.Model):
application_id = models.IntegerField()
version_id = models.IntegerField()
# some other attributes
其中application_id
和version_id
一起确定Application
条目,因为一个应用程序可能有多个版本,并且具有最大version_id
的条目是应用程序的当前版本。
目标是找到所有应用程序的当前版本。 SQL(在MySQL中)类似于:
SELECT
*
FROM application AS app
WHERE version_id = (SELECT max(version_id)
FROM application
WHERE application_id = app.application_id);
怎么做到这一点?
请注意,这里的对象是过滤QuerySet
,而不是仅获取最大的version_id
,这将像使用GROUP BY
一样简单,或者在django中使用values()
,然后是annotate()
。我也对当前版本的其他属性感兴趣。
我自己想通了。 OuterRef
和SubQuery
是诀窍,它是Django 1.11中的新功能,正如here所述。
from django.db.models import OuterRef, Subquery, F
def filter_to_current(qs: QuerySet):
qs = qs.annotate(current=Subquery(qs.filter(application_id=OuterRef('application_id'))
.order_by('-version_id').values('version_id')[:1])) \
.filter(version_id=F('current'))