如何在Django中按字段分组并获取分组内含全字段的最新记录?
解决Django按分组获取最新完整记录的问题
你的问题出在values('type')的使用上:当你用values()指定字段后,Django的查询集只会保留这些指定字段,再加上annotate生成的聚合字段,所以结果里只有type和latest_date。要获取每组的完整最新记录,可以用以下两种常用方法:
方法一:子查询过滤法
先通过子查询获取每个type对应的最新created_at,再用这个结果过滤主查询,得到完整的用户记录:
from django.db.models import Subquery, OuterRef # 子查询:获取每个type的最新created_at latest_type_dates = User.objects.filter( type=OuterRef('type') ).values('type').annotate( latest_date=Max('created_at') ).values('latest_date') # 主查询:筛选出created_at等于对应组最新日期的记录 result = User.objects.filter(created_at__in=Subquery(latest_type_dates))
如果同一type下有多个记录的created_at相同且都是最新值,这个方法会返回所有符合条件的记录。
方法二:窗口函数法(Django 2.0+)
利用Django的窗口函数RowNumber,按type分区、created_at降序排序,然后取每组的第一条记录:
from django.db.models import Window, F from django.db.models.functions import RowNumber result = User.objects.annotate( row_num=Window( partition_by=F('type'), # 按type分组 order_by=F('created_at').desc() # 按created_at倒序,最新的排第一 ) ).filter(row_num=1)
这个方法更简洁高效,且能精准控制每组只取一条最新记录(即使同组有多个相同的最新日期,也只会返回排序后的第一条)。执行后result就是包含所有字段的User实例查询集,你可以直接获取id、name等字段。
内容的提问来源于stack exchange,提问作者reza_khalafi
相关产品推荐
相关产品推荐

