Django分组聚合添加额外字段后失效,如何保留分组并包含其他字段?
解决方案
要保留按sku和track_name的分组逻辑,同时获取每组的track_id示例和location字段,核心是只把分组依据字段放在values()里,其他需要的字段通过聚合函数提取分组内的单个示例值。
方法1:使用First聚合函数(Django 3.2+ 支持)
First会取分组内第一条记录的对应字段值,刚好满足你“获取一个示例”的需求:
from django.db.models import Count, First track_listing = (Tracks.objects .values('sku', 'track_name') # 仅保留分组依据字段 .annotate( variations=Count('sku'), sample_track_id=First('track_id'), # 提取分组内第一个track_id sample_location=First('location') # 提取分组内第一个location ) .order_by() )
方法2:兼容低版本Django(用Max/Min替代)
如果你的Django版本低于3.2,First不支持,可以用Max或Min来获取分组内的任意一个示例值(只要分组内有值就能返回):
from django.db.models import Count, Max track_listing = (Tracks.objects .values('sku', 'track_name') .annotate( variations=Count('sku'), sample_track_id=Max('track_id'), sample_location=Max('location') ) .order_by() )
为什么之前的写法会破坏分组?
Django中values()里的所有字段都会作为SQL的GROUP BY依据,你之前把track_id加入values()后,分组逻辑变成了sku + track_name + track_id的组合,同一个sku+track_name下不同的track_id会被拆分成不同分组,自然就破坏了原本的聚合结果。
内容的提问来源于stack exchange,提问作者Byte Insight
相关产品推荐
相关产品推荐

