Django聚合统计踩坑记

    前端提了个需求,需要统计各版本的使用情况。在网上搜寻一番,发现aggregate和annotate方法可以很简单的实现这个功能,在使用过程中遇到了个坑,就是无论是按照官方的帮助文档,还是各大论坛的教程,都不能获取到正确的结果。

    网上千篇一律的写法大致是这样的。

Student.objects.values('name').annotate(Count('hobbies')) 

    或者是这样的:

Student.objects.annotate(hobby_count=Count('hobbies')).values('name', 'hobby_count')

    官方的教程是这样的:

pubs=Publisher.objects.annotate(num_books=Count('book'))

    这些语句在实际环境里面就是执行不了,执行得到的都是没有分组的结果,并没有起到统计的作用。

    定位这个问题最后还是用到了SQL语句,在上述语句后面使用.query属性可获得对应的SQL语句,如下是调试时打印的SQL语句:

SELECT `testbench_testbench`.`location`, COUNT(`testbench_testbench`.`version`) AS `a` FROM `testbench_testbench` GROUP BY `testbench_testbench`.`location`, `testbench_testbench`.`created_time` ORDER BY `testbench_testbench`.`created_time` ASC

    可以发现 group by后面有两个字段,一个是location,一个是created_time。此是因为我们在定义models时定义了ordering属性,至此原因明确了,在语句中加上一段去除group by的默认设置即可,其方法是添加.order_by()方法,如:

TestBench.objects.order_by('version').values('version').annotate(num=Count('version')).values('version','num')

总结

    对于Django数据库的操作如果出现一些奇怪的问题,可以打印出SQL语句,根据SQL语句分析问题的关键点,找出对应方法。

你可能感兴趣的:(Django聚合统计踩坑记)