Django中按年月分组排序后如何注解模型其他字段?
解决方案
你可以通过以下两种方式获取每个月最后一天数据的完整模型字段,避免values()带来的限制:
方法一:子查询过滤(兼容低版本Django)
先通过子查询算出每个年月对应的最后一天created_at,再用这个结果过滤主查询集,就能拿到完整的模型实例:
from django.db.models import Max, OuterRef, Subquery # 子查询:获取每个year、month对应的最大created_at monthly_last_day = ( self.model.objects .with_months() .with_years() .filter(year=OuterRef('year'), month=OuterRef('month')) .values('year', 'month') .annotate(last_day=Max('created_at')) .values('last_day') # 只取最后一天的时间值,用于子查询匹配 ) # 主查询:过滤出created_at等于对应年月最后一天的完整数据 qs = self.model.objects.with_months().with_years().filter(created_at=Subquery(monthly_last_day))
方法二:窗口函数(Django 2.2+推荐)
利用RowNumber()窗口函数,按年月分组后给数据按created_at降序排号,取每组的第1条(即最后一天的数据):
from django.db.models import Window, F from django.db.models.functions import RowNumber qs = ( self.model.objects .with_months() .with_years() .annotate( # 按年月分组,created_at降序,给每条数据分配行号 row_num=Window( expression=RowNumber(), partition_by=[F('year'), F('month')], order_by=F('created_at').desc() ) ) .filter(row_num=1) # 只保留每组的第一行(最后一天的数据) )
两种方法返回的qs都是完整的模型QuerySet,你可以直接访问模型的所有字段,不会破坏分组逻辑。
内容的提问来源于stack exchange,提问作者Burakhan Aksoy
相关产品推荐
相关产品推荐

