You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:00:58