Django:模型_ORM聚合函数

聚合函数

1、如果使用原生SQL来操作数据库,则可以使用聚合函数来提取数据等。比如提取你某个商品销售的数量,那么可以使用Count函数,如果想要知道商品销售的平均价格,那么可以使用AVG函数

2、在Django的ORM模型中同样可以使用聚合函数来处理数据。在ORM模型中,聚合函数是通过aggregate()等方法来实现的

3、上面第二点的意思为:所有的聚合函数都不能单独的执行,需要放在一些可以执行聚合函数的方法中去执行,比如aggregate()方法

4、所有的聚合函数都是放在"django.db.models"下面的。因此我们在使用聚合函数时,需要导入对应的模块

5、以下例子都是在下面的模型上进行的

例1:模型类
⑴编辑模型
Django:模型_ORM聚合函数

⑵存入数据
Django:模型_ORM聚合函数⑶查看数据
Django:模型_ORM聚合函数
Django:模型_ORM聚合函数
Django:模型_ORM聚合函数

 

 

平均值:Avg

作用:返回某一些数据(列)的平均值

例2:

⑵编辑视图
Django:模型_ORM聚合函数

注:上面例子中
1、执行聚合函数后,返回的是一个字典类型的值,如:{'price__avg': 150.0}
    ⑴聚合函数执行完成后,会自动的给这个计算结果取一个名字。取名的规则默认是:字段(列)名__聚合函数名
    ⑵如果不想使用Django默认的名字的话,可以在使用聚合函数的时候传递一个关键字参数进去,参数的名字就是聚合函数执行完成的名字

2、aggregate()方法返回的是一个字典类型的值,不是一个QuerySet对象。这个字典中的Key就是聚合函数的名字,值就是聚合函数执行后的结果

3、因为aggregate()方法返回的不是一个QuerySet对象,因此就不能使用"实例名.query"属性来查看聚合函数对应的SQL语句了
    ⑴只有返回结果是QuerySet对象时,才能使用"实例名.query"属性来查看对应的SQL语句
    ⑵而是需要使用Django其他的方法来查看:connection.queries。这个方法包含了很多的查询语句列表

4、通过查看上面例子返回的对应的SQL语句,可以看到实际起作用的SQL语句是:SELECT AVG(`book`.`price`) AS `price__avg` FROM `book`'(其他的是Django在执行聚合函数SQL语句前执行的,可以不管)

 

 

总数:Count

作用:获取指定的对象的个数

例3:
⑴查看数据
Django:模型_ORM聚合函数

⑵编辑视图:统计有多少个邮箱(包括重复的)
Django:模型_ORM聚合函数

⑶编辑视图:统计有多少个不同的邮箱
Django:模型_ORM聚合函数

 

 

最大(小)值:Max和Min

作用:获取执行对象的最大值和最小值

例4:
⑴查看数据
Django:模型_ORM聚合函数

⑵编辑视图
Django:模型_ORM聚合函数

⑶编辑视图
    调用聚合函数的aggregate()等方法中可以同时存在多个聚合函数
Django:模型_ORM聚合函数

 

 

总和:Sum

作用:求指定对象的总和

例5:
⑴编辑视图
Django:模型_ORM聚合函数


⑵编辑模型
Django:模型_ORM聚合函数

⑶查看数据
Django:模型_ORM聚合函数

⑷链式调用
    只要返回的是一个QuerySet对象,那么就可以链式调用聚合函数
Django:模型_ORM聚合函数

 

 

F表达式

1、作用:动态获取某个字段上的值(获取后怎么操作就看我们自己了)。并且这个F表达式,不会真正的去数据库中查询,它相当于只是起一个标识的作用

2、F表达式是用来优化ORM操作数据库的

3、F表达式中的参数就是我们需要提取的字段名

Django:模型_ORM聚合函数

例6:
⑴查询执行前的价格
Django:模型_ORM聚合函数

⑵编辑视图
Django:模型_ORM聚合函数

⑶查看执行后的价格
Django:模型_ORM聚合函数


Django:模型_ORM聚合函数

 

 

Q表达式

作用:对对象的复杂查询

例7:
Django:模型_ORM聚合函数

 

 

补充:aggregate和annotate

aggregate

1、aggregate:返回使用聚合函数后的字段和值

2、aggregate的中文意思是聚合, 源于SQL的聚合函数。Django的aggregate()方法作用是对一组值(比如queryset的某个字段)进行统计计算,并以字典(Dict)格式返回统计计算结果。django的aggregate方法支持的聚合操作有AVG/COUNT/MAX/MIN/SUM等

 

annotate

1、annotate:在原来模型字段的基础之上添加一个使用了聚合函数的字段,并且在使用聚合函数的时候,会使用当前这个模型的主键进行分组(group by)

2、annotate的中文意思是注释,一个更好的理解是分组(Group By)。如果你想要对数据集先进行分组然后再进行某些聚合操作或排序时,需要使用annotate方法来实现。与aggregate方法不同的是,annotate方法返回结果的不仅仅是含有统计结果的一个字典,而是包含有新增统计字段的查询集(queryset).

3、annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)

4、总结:跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询:使用"基于下划线"的查询方式


例8:
⑴编辑模型
Django:模型_ORM聚合函数

⑵存入数据
Django:模型_ORM聚合函数

⑶查看数据
Django:模型_ORM聚合函数
Django:模型_ORM聚合函数

注:
上面新增了一个模型类:用来存储每本图书的订单(图书id和价格),并且该模型内的book属性通过外键关联Book模型类

例9:使用aggregate()方法来实现求订单价格的平均值
⑴编辑视图
Django:模型_ORM聚合函数


例10:使用annotate()方法来实现求每类图书订单价格的平均值
⑴编辑视图
Django:模型_ORM聚合函数
Django:模型_ORM聚合函数

注:
1、在计算"每一本图书的价格"时
    ⑴最终查询的是:"平均价格",查询的数据在子表中
    ⑵视图函数中的SQL语句是从"Book"模型类开始的,即从主表(Book)开始的,因此为"反向查询",因此使用的方法为"小写模型名__字段名"

2、不管最终查询的数据是在子表中还是在主表中,只要是从"子表开始查询到主表",那么就是正向查询,"从主表查询到子表就是反向查询"。只是说正向查询和反向查询的写法不一样
    ⑴外键属性字段定义在哪个模型类中,哪个模型类就是子表

 

aggregate和annotate的区别

相同点:
    这两个方法都可以执行聚合函数
    
不同点:
    ⑴aggregate返回的是一个字典,在这个字典中存储的是这个聚合函数执行的结果。而annotate返回的是一个QuerySet对象
    ⑵aggregate不会做分组,而annotate会使用"group by"子句进行分组,只有调用了"group by"子句才能对每一条数据求聚合函数的值