Django之ORM操作(聚合 分组、F Q)
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)的更多相关文章
- Django之ORM操作
Django之ORM操作 前言 Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计 ...
- 【Django】ORM操作#2
目录 必知必会的13条查询方法 单表查询之神奇的双下划线 一对多 ForeignKey 多对多 ManyToManyField 在Python脚本中调用Django环境 Django终端打印SQL语句 ...
- Django之ORM操作(***)
Django之ORM操作(***) http请求的流程: url--> 视图view(模板+数据库) --> ORM的功能: 可以转换SQL语句,并做操作. ORM操作数据表: -创建表: ...
- 【Django】ORM操作#1
目录 一.介绍 概念 由来 优势 劣势 总结 二.Django中的ORM Django项目使用MySQL Model 快速入门 1. AutoField 2. IntegerField 3. Char ...
- Django中ORM的聚合索引
Django中ORM的聚合索引 在Django中,聚合函数是通过aggregate方法实现的,aggregate方法返回的结果是一个字典 在使用时需要先导入模块from django.db.mod ...
- django的orm操作优化
django的orm操作优化 models.py from django.db import models class Author(models.Model): name = models.Char ...
- ORM( ORM查询13种方法3. 单表的双下划线的使用 4. 外键的方法 5. 多对多的方法 ,聚合,分组,F查询,Q查询,事务 )
必知必会13条 <1> all(): 查询所有结果 <2> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或 ...
- python-day71--django多表双下划线查询及分组聚合及F/Q查询
#====================================双下划线的跨表查询===============# 前提 此时 related_name=bookList 属性查询: # 查 ...
- Django之ORM操作(重要)
Django ORM操作 一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> get(**kwargs): 返回与所给 ...
随机推荐
- c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用
c/c++ 类成员变量,成员函数的存储方式,以及this指针在c++中的作用 c++不会像上图那样为每一个对象的成员变量和成员函数开辟内存空间, 而是像下图那样,只为每一个对象的成员变量开辟空间.成员 ...
- 用emacs 阅读 c/c++ 代码
在emacs编程中有以下需求 从调用一个函数的地方跳转到函数的定义的地方 或是反过来从函数定义的地方列出所有调用这个函数的地方 实现办法 需要安装以下软件 gnu global(阅读源代码的工具)官网 ...
- linux (fedora 28) 制作启动U盘,启动盘
最近需要安装一款Linux, 由于使用的计算机系统为 fedora 28, 所以只能在linux 制作U盘 使用 df 或者 fdisk -l 查看 U盘文件: Disk /dev/sdb: byte ...
- Cs231n课堂内容记录-Lecture1 导论
Lecture 1 视频网址:https://www.bilibili.com/video/av17204303/?p=2 https://zhuanlan.zhihu.com/p/21930884? ...
- 本学期c#总结
本学期我学习了C#编程认识到了什么是方法什么是关键字,和代码的作用.认识到了编程不仅仅是对一个程序的编程,也是对数据的编程.程序是由数据组成的.c#本身就是一种语言,C#适用于生成面向.net fr ...
- JDK动态代理和cglib代理详解
JDK动态代理 先做一下简单的描述,通过代理之后返回的对象已并非原类所new出来的对象,而是代理对象.JDK的动态代理是基于接口的,也就是说,被代理类必须实现一个或多个接口.主要原因是JDK的代理原理 ...
- 合并两个有序数组的golang实现
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n. ...
- Loj 3058. 「HNOI2019」白兔之舞
Loj 3058. 「HNOI2019」白兔之舞 题目描述 有一张顶点数为 \((L+1)\times n\) 的有向图.这张图的每个顶点由一个二元组 \((u,v)\) 表示 \((0\le u\l ...
- Linux发展史-简简简易版
"蛋-人-人-人" unix诞生 unix 贝尔实验室 人-谭教授 谭宁邦 minix mini unix 主要用于教学 人-斯托曼 stallman 我要开发出一个系统:自由 开 ...
- 16.ajax_case04
# 抓取金色财经快讯接口 # https://www.jinse.com/lives import requests import json header = { 'Accept': 'text/ht ...