Django中统计指定前缀的Animal模型数据数量异常问题
问题解决
你的代码存在两个核心问题导致统计错误:
- 误用
Count:Count会统计所有非空值(包括Case返回的0),所以最终每个类别统计的都是总条目数。应该用Sum来累加符合条件的1值。 - 匹配字符串错误:示例数据里是
cat开头,但代码里写的是text__startswith="cats",多了末尾的s,导致无法匹配到目标数据。
修正后的代码如下:
from django.db.models import Sum, Case, When, IntegerField queryset = models.Animal.objects.all() animal_summary = ( queryset .annotate( cats=Sum( Case( When(text__startswith="cat", then=1), default=0, output_field=IntegerField(), ) ), dogs=Sum( Case( When(text__startswith="dog", then=1), default=0, output_field=IntegerField(), ) ), fish=Sum( Case( When(text__startswith="fish", then=1), default=0, output_field=IntegerField(), ) ) ) .values('cats', 'dogs', 'fish') .first() # 取出唯一的统计结果字典 ) return {"animal_count": animal_summary}
关键说明:
- 替换
Count为Sum:Sum会将符合条件的1累加,不符合的0不影响结果,正确统计每个类别的数量。 - 修正匹配字符串:把
"cats"改为"cat","dogs"改为"dog",和数据开头的动物名称一致。 - 合并annotate:将三个独立的
annotate合并为一个,代码更简洁高效。 - 添加
.first():因为整个查询是对全表做一次统计,结果只有一条,用.first()直接取出字典格式的统计结果,避免返回QuerySet。
针对你的示例数据,运行后会得到:
{"animal_count": {"cats": 1, "dogs": 1, "fish": 0}}
内容的提问来源于stack exchange,提问作者Ajax
相关产品推荐
相关产品推荐

