Django之ORM操作(聚合 分组、F Q)

  

  聚合

  aggregate()是QuerySet的一个终止子句,也就是说,他返回一个包含一些键值对的字典,在它的后面不可以再进行点(.)操作.

   键的名称是聚合值的标识符,只是计算出来的聚合值.键的名称是按照字段和聚合函数的名称自动生成出来的.

  聚合函数的导入

from django.db.models import Max, Min, Sum, Avg, Count

  

  简单使用示例:

  查询所有书的平均价格.

 from django.db.models import Avg, Sum, Max, Min, Count

 ret = models.Book.objects.all().aggregate(Avg("price"))

 >>> {'price__avg': 13.233333}  # price__avg 是自动成出来的,前边是聚合的字段,后边是聚合函数的名称.

  

  当需要为聚合值指定一个名称,可以向聚合子句提供它.

from django.db.models import Avg, Sum, Max, Min, Count

models.Book.objects.aggregate(average_price=Avg('price'))  # average_price 为自己指定的名称.
>>> {'average_price': 13.233333}

  当需要生成不止一个聚合时,可以向aggregate()子句中添加另一个参数.

  查询所有图书价格的平均值 最大值 最小值.

 from django.db.models import Avg, Sum, Max, Min, Count

 models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price"))  # 

 >>> {'price__avg': 13.233333, 'price__max': Decimal('19.90'), 'price__min': Decimal('9.90')}

  查询所有图书中最高的价格和平均价格

 from django.db.models import Max, Avg

 ret = models.Book.objects.aggregate(Max('price'), avg=Avg('price'))  # 

  分组

  现有员工表如下:

  需求:

    按照部门分组求平均工资

  ORM操作如下:

 from django.db.models import Avg

 models.Employee.objects.values("dept").annotate(avg=Avg("salary").values("dept", "avg")  # 

  按照哪个字段分组,就将哪个字段写在objects后面的values中.

  注意:

    分组使用的是annotate(),他不是一个终止子句,他的后边可以跟其他操作.

  连表查询:

    表格如下:

  按照部门分组求平均工资:

 from django.db.models import Avg

 models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")  # 

  按照部门分组,就从部门表上开始查,聚合函数Avg()中写需要差的字段,按照双下划线的方法找到字段.

  其他示例:

  统计每一本书的作者的数量

 from app01 import models
from django.db.models import Count ret = models.Book.objects.annotate(Count('author')).values() #

  查询每个出版社出版的图书中价格最低的

  方式一:

 from app01 import models
from django.db.models import Min ret = models.Publisher.objects.annotate(Min('book__price')).values() #

  从出版社表查,聚合函数Min()中写需要查询的字段,使用双下滑线(__)的方法查询到需要的字段.

  方式二:

 from app01 import models
from django.db.models import Min ret = models.Book.objects.values('publisher__name').annotate(min=Min('price')) #

  从书表中查,objects后面的values()中写分组依据的字段名.然后跟annotate()中写聚合函数,聚合函数中写查询的字段.

  查询作者大于1的图书

 from app01 import models
from django.db.models import Count ret = models.Book.objects.annotate(count=Count('author')).filter(count__gt=1).values() #

  从书表中查询,先统计每一本书的作者的数量,然后使用filter()过滤出符合条件的对象.

  查询每位作者所出书的总价格

 from app01 import models
from django.db.models import Sum ret = models.Author.objects.annotate(Sum('books__price')).values() #

  从作者表查询,聚合函数Sum()中填写查询的字段

  F

  在此之前我们构造的过滤器都只是将字段与某个常量作比较,如果将两个字段做比较时,可以使用F().F()的实例可以再查询中引用字段,来比较同一个model实例(对象)中的两个不同字段的值.

  简单点说就是可以用来动态数据对比查询.

  F的导入

from django.db.models import F

  查询销量大于库存的图书

from django.db.models import F

ret = models.Book.objects.filter(sale__gt=F('kucun')).values()  # 

  F的用法是F('字段名'),F()是用来取值的.

  将所有书的销量更新为原来的2倍.

 from app01 import models
from django.db.models import F ret = models.Book.objects.all().update(sale=F('sale') * 2) #

  可以进行翻倍操作.

  PS:

    知识补充 ---> .update()  更新

    仅对选中的QuerySet对象进行更新,速度快.

 from app01 import models

 ret = models.Book.objects.filter(id=2).update(sale=100)  # 

  将id为2的书的销量设置为100.

  将所有书的销量更新为原来的2倍.

1 from app01 import models
2 from django.db.models import F
3
4 ret = models.Book.objects.all().update(sale=F('sale') * 2) #

  可以进行翻倍操作.

    知识补充 ---> .save()  修改后进行保存.

    对所有对象都进行保存,操作数据量大,速度慢.

 from app01 import models

 obj = models.Book.objects.get(id=2)
obj.sale=''
obj.save()

  将id为2的书的销量设置为1000.

  Q

    filter()等方法中的关键字参数查询都是一起进行'and'的,如果需要进行更加复杂的查询,可以使用Q对象.

  示例:

    查询id小于等于3或者id大于等于6的书

 from app01 import models
from django.db.models import Q ret = models.Book.objects.filter(Q(id__lte=3) | Q(id__gte=6)) #

    Q()写在filter()中,使用或(or)查询是每个Q()使用管道符(|)连接,管道符表示或(or)的关系.

    查询id大于等于10并且销量大于等于3000的书.

 from app01 import models
from django.db.models import Q ret = models.Book.objects.filter(~Q(price__gte=10) & Q(sale__gte=3000)).values() #

  

  使用&连接时表示and.

Django之ORM操作(聚合 分组、F Q)的更多相关文章

  1. Django之ORM操作

    Django之ORM操作 前言 Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计 ...

  2. 【Django】ORM操作#2

    目录 必知必会的13条查询方法 单表查询之神奇的双下划线 一对多 ForeignKey 多对多 ManyToManyField 在Python脚本中调用Django环境 Django终端打印SQL语句 ...

  3. Django之ORM操作(***)

    Django之ORM操作(***) http请求的流程: url--> 视图view(模板+数据库) --> ORM的功能: 可以转换SQL语句,并做操作. ORM操作数据表: -创建表: ...

  4. 【Django】ORM操作#1

    目录 一.介绍 概念 由来 优势 劣势 总结 二.Django中的ORM Django项目使用MySQL Model 快速入门 1. AutoField 2. IntegerField 3. Char ...

  5. Django中ORM的聚合索引

    Django中ORM的聚合索引   在Django中,聚合函数是通过aggregate方法实现的,aggregate方法返回的结果是一个字典 在使用时需要先导入模块from django.db.mod ...

  6. django的orm操作优化

    django的orm操作优化 models.py from django.db import models class Author(models.Model): name = models.Char ...

  7. ORM( ORM查询13种方法3. 单表的双下划线的使用 4. 外键的方法 5. 多对多的方法 ,聚合,分组,F查询,Q查询,事务 )

    必知必会13条 <1> all(): 查询所有结果 <2> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或 ...

  8. python-day71--django多表双下划线查询及分组聚合及F/Q查询

    #====================================双下划线的跨表查询===============# 前提 此时 related_name=bookList 属性查询: # 查 ...

  9. Django之ORM操作(重要)

    Django ORM操作 一般操作 看专业的官网文档,做专业的程序员! 必知必会13条   <1> all(): 查询所有结果 <2> get(**kwargs): 返回与所给 ...

随机推荐

  1. PHP实现邮件的自动发送

    最近做一个邮箱验证的功能,研究了一会,搞定了邮件的自动发送.下面用qq邮箱作为演示,一步一步来解释: 代码下载地址 首先,就是做到邮件的发送,代码如下: <?php//邮件发送require ' ...

  2. CSS2属性选择器和css3选择器的用法和区别

    兄弟们,这是我第一次写博客,希望对进来的人有用,写的不好别喷哈,谢谢. css2属性选择器: 1.[attribute] 例子:   [title] 解释:   选择含有  title  属性的所有元 ...

  3. K-means算法的matlab程序(初步)

    K-means算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648369.html 文章中已经介绍了K-means算法,现在用matlab程序实现 ...

  4. 我的第一个SolidWorks图

    1. 学习到的知识点 2. 完成的工程图 3. 感受 学习是一种快乐,学到新的知识要学会分享,只要坚持,就有那么一点点的成就. 4. 参考 SolidWorks帮助文档

  5. servlet温习

    servlet是Javaweb的核心,它实质上就是运行在服务器端的Java代码 1.简介 servlet是运行在服务器端的小程序,是sun公司提供的一套规范(接口),用来处理用户的请求,响应给浏览器的 ...

  6. P2066 机器分配 DP

    题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...

  7. RocketMQ实现事务消息

    在RocketMQ4.3.0版本后,开放了事务消息这一特性,对于分布式事务而言,最常说的还是二阶段提交协议,那么RocketMQ的事务消息又是怎么一回事呢,这里主要带着以下几个问题来探究一下Rocke ...

  8. ndim 与 shape的区别

    [[ ., ., .], [ ., ., .]] 在上面这个例子中,数组的ndim为2(它有两个维度(简单的辨别两层方括号)). 第一个维度的长度为2,也就是有两个子数组 第二个维度的长度为3,也就是 ...

  9. iptables 从一台机到另一台机端口转发

    启用网卡转发功能#echo 1 > /proc/sys/net/ipv4/ip_forward 举例:从192.168.0.132:21521(新端口)访问192.168.0.211:1521端 ...

  10. 二.css介绍

    一.三种引入样式1.内嵌样式:写在html中 style标签里面2.行内样式:写在具体的标签的style属性3.引入外部样式表:可以将样式规则写在外部文件,再引入到html中 <link typ ...