如何统计Django Queryset中指定字段各取值对应的关联对象数量
实现方案
1. 排序逻辑说明
你现有代码里的order_by('-poller_category')如果没有其他业务需要(比如同时要返回排序后的Poller列表),仅做分类统计的话可以直接删掉,聚合统计不需要依赖排序,保留反而会增加不必要的查询开销。
2. 统计代码实现
直接用Django ORM的annotate+Count聚合函数即可实现按分类统计,代码如下:
from django.db.models import Count # 先过滤符合条件的Poller,再按分类聚合统计 counts_qs = Poller.objects.filter(created_by__username=username)\ .values('poller_category__poller_category')\ .annotate(total=Count('poller_id')) # 转成你需要的字典格式,值可以按需转字符串或者保留数字 counts = {item['poller_category__poller_category']: str(item['total']) for item in counts_qs}
上面代码得到的counts就完全符合你要的{'Sport' : '2', 'Tech' : '2', 'Fashion' : '1'}格式。
补充说明
- 如果你的场景中存在
poller_category为null的Poller数据,聚合结果里会出现key为None的项,如果你不需要这类数据,可以在filter里多加一个条件poller_category__isnull=False过滤掉。 - 如果你还要同时用到原来排序后的Poller查询集,也可以基于你已经得到的
qs变量做聚合,不需要重复写过滤逻辑:
# 基于已有的qs做统计 counts_qs = qs.values('poller_category__poller_category').annotate(total=Count('poller_id')) counts = {item['poller_category__poller_category']: str(item['total']) for item in counts_qs}
内容的提问来源于stack exchange,提问作者JSRB
相关产品推荐
相关产品推荐

