Django 2中按日期分组统计Log模型记录数的问题
解决Django按日期聚合统计时日期重复的问题
这个坑我之前踩过!你遇到的同日期重复出现的情况,几乎可以肯定是因为你的Log模型设置了默认排序(ordering元组),或者当前查询集自带了排序规则导致的。
Django ORM有个容易忽略的特性:当执行分组查询时,如果查询集里存在排序字段(不管是模型默认的还是手动添加的),ORM会自动把这些排序字段也加入到SQL的GROUP BY子句里。这就意味着,哪怕两条记录的date完全相同,但排序字段的值不一样,它们会被分成不同的组,最终返回多条同日期的拆分结果。
两种简单方案解决问题:
方案1:清空查询集的排序规则
在查询末尾加上.order_by(),移除所有默认或手动添加的排序字段,让ORM只按你指定的date字段分组:
from django.db.models import Count from django.db.models.functions import TruncDate result = Log.objects.annotate(date=TruncDate('created_at'))\ .values('date')\ .annotate(c=Count('id'))\ .order_by()
方案2:明确指定按date字段排序
如果你需要最终结果按日期排序,直接指定按date排序即可,ORM会自动调整GROUP BY子句,只保留date字段:
from django.db.models import Count from django.db.models.functions import TruncDate result = Log.objects.annotate(date=TruncDate('created_at'))\ .values('date')\ .annotate(c=Count('id'))\ .order_by('date')
额外小提示:
- 用
Count('id')或者Count('*')效果完全一致,都是统计每个分组的记录总数。 - 执行完上面的代码后,你就能得到每个日期唯一的聚合结果,比如
{'date': datetime.date(2018, 1, 17), 'c': 4}这样的正确数据了。
内容的提问来源于stack exchange,提问作者Jahongir Rahmonov
相关产品推荐
相关产品推荐

