Django ORM从Product表出发对关联字段分组并统计数量的实现方法
正确查询写法
首先需要从 django.db.models 导入依赖的函数,按如下方式编写查询即可得到期望结果:
from django.db.models import Count # 基础写法,返回字段带关联前缀 queryset = Product.objects.filter(name__icontains="some text") \ .values("options__vtype", "options__text") \ .annotate(count=Count("pk")) \ .order_by("options__vtype")
如果希望返回的字段不带options__前缀,可读性更高,可以用 F 表达式先做别名处理:
from django.db.models import Count, F queryset = Product.objects.filter(name__icontains="some text") \ .annotate( vtype=F("options__vtype"), text=F("options__text") ) \ .values("vtype", "text") \ .annotate(count=Count("pk", distinct=True)) \ .order_by("vtype")
相关说明
- 之前写法的核心问题是
Count()没有传入统计维度参数,Django 无法识别聚合规则,导致计算结果不正确。 Count中加distinct=True是为了避免单个Product存在多个重复(vtype, text)的Option时,统计结果偏大,更符合「统计符合条件的Product中该属性组合出现次数」的需求。如果业务逻辑已经限制了同一个Product下不会有重复的(vtype, text)组合,可以去掉该参数。- 末尾的
order_by是为了保证返回结果按属性类型排序,和示例结果顺序一致,如果不需要固定排序可以直接去掉。
内容的提问来源于stack exchange,提问作者akinator
相关产品推荐
相关产品推荐

