Django分组聚合查询实例分享


Posted in Python onApril 29, 2020

多表查询

1. 增删改

一对多:先一后多,外键可以为对象或依赖表的主键(publish and book)

publish = Publish.objects.create()
Book.objects.create(....publish=publish|publish_id=publish.id)

删: 默认存在级联删除

改: book修改外键,外键一定存在

多对多:

关系表的获取(book(主键) and author) book.author

增:book.author.add(作者对象们|主键们)

删: clear()清除 remove() 可删除单个作者

改: set([作者对象们|主键们])

2. 查

基于对象,正向找属性,反向找类名小写,多条记录类名小写_set

book.publish.first().name (book 一定是对象,不是queryset)
publish.book_set.first().name

基于双下划线:

Book.objects.filter(id=1).values('publish__name')[0] (values 查出的也是queryset)
publish.values('book__name')

今日内容

1. 分组查询: 聚合结果 group_by()

2. 聚合函数

3. 字段

分组查询(单独聚合查询 and 分组聚合查询---基于mysql)

Book: id name price publish_date publish

聚合函数可以单独使用 ---- 整张表是一个大组

select max(price) from book

聚合函数在分组下使用

select max(price) as high_price from book group by publish having high_price > 50;

聚合查询---基于ORM

聚合函数的使用场景:

单独使用:不分组,只查聚合结果

分组使用: 按字段分组,可查分组字段与聚合结果

导入聚合函数:

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

单独聚合查询:aggregate (聚集,合集)---不分组

# 语法

# 聚合函数: Max, Min,Sum, Avg, Count

aggregate(别名=聚合函数('字段‘)

规则:

1. 可以同时对多个字段进行聚合处理: aggregate(name1= , name2= ...)

2. 是QuerySet 对象的方法(all,filter)

3. 返回值为dict类型

4. 在aggregate之前的values操作没作用,被忽略

例: 所有书中最贵的书的价格

dic = Book.objects.all().aggregate(high_price=max('price),low_price=min('price'))

分组聚合查询: annotate (注释,做注解) --- 分组

# 语法
values('分组字段').annotate(别名=聚合函数(‘字段').filter(聚合别名条件).values('取分组字段','取聚合字段别名'))

规则:

1. values --- annotate 分组组合, values控制分组的字段,annotate控制聚合字段

2. values 可以按多个字段分组values('字段1‘,'字段2‘)

3. 可以同时对多个字段进行聚合处理 annotate(别名1=max('price'),别名2=min('price'))

4. 分组后的filter 代表having判断,只对聚合字段进行条件判断,(参数为非聚合或分组进行条件判断代表where判断)

5. 取字段值 values() 省略默认取所有分组字段和聚合字段,也可以自己定义(对非分组或非聚合字段,该字段自动被变成分组字段)

# 案例:每个出版社出版的最贵的书的价格高于50元的出版社名与最高价格

# 思路:按出版社分组(从book出发),high_price=max('price'), filter(high_price__gt=50)

# 每个组的价格最贵的

Book.objects.all().values('publish__name').annotate(high_price=max('price').filter(high_price__gl=50).values('publish__name','high_price'))

字段属性

1. null: 默认Fasle(默认字段不能为空) , True 表示字段可为null
2. blank: 默认False, True 表示字段可以为空
3.choice: 限制了该选项字段值必须是指定的choice 中的一个 (元组套元组)
sex = models.SmallIntegerField(choice=((1,'man'),(2,'female')))
obj.get_sex_display()

有choices 这个字段的: 要取得'女‘或'男‘, get_字段名sex_display() --超出失效
4. db_column: 自定义字段名
db_column='gender' 起别名该sex
5. db_index : True 设置索引
6. default: 字段默认值
7. editable: 默认为True, False: 不在 admin 界面显示
8. primary_key : TRUE 为主键,
9. unique: true 字段值不可重复

字段

1. AutoField(): 默认自增主键(primary_key=True)
2. BooleanField(): 布尔字段, 对应database tinyint 类型
3. CharField(): 字符类型(默认不为空)
max_length=20,null=True 可以为空
4. DateField(): 年月日
auto_now = True 数据别更新就会更新时间
auto_now_add = True 数据第一次产生时
5. DateTimeField(): 年月日时分秒
auto_now = True 数据别更新就会更新时间
auto_now_add = True 数据第一次产生时
6. DecimalField(): 混合精度的小数类型
max_digits = 5, 含小数为的最大位数
decimal_places = 2 , 小数位数
7. IntegerField(): 整型

不常用字段

关系字段

1. ForeignKey(): 外键字段
to= 关联模型类 (一对多)
to_file = 关联字段,省略默认关联主键
on_delete (外键关联数据被删除时的操作)
models.CASCADE 级联删除
modles.PROTECT 抛出异常
models.SET_NULL 设置空值
modles.SET_DEFAULT 设置默认值
models.SET(value) 自定义值
related_name 自定义反向查询的字段名
db_constraint=False, 取消关联,但还可以使用链表查询
总结: models.ForeignKey(to='related class name', null=True,on_delete=models.SET_NULL,db_constraint=False,related_name='本类名小写')
2. OneToOneField(): 一对一字段
同外键
3, ManyToManyField() :多对多关系
to = 关联模型类
through=关联关系类
through_fields关联关系表中(本身字段,关联字段)

断开外键关联的ForeignKey使用(一对多,一对一)

# 一对多查询 ----(publish and book)
# 方式一 : 不使用外键,在book 中添加 publish_id 属性
# 不在支持Django ORM 链表查询语法

# class Book(models.Model):
# name = models.CharField(max_length=20)
# publish_id = models.IntegerField(null=True)
#
# class Publish(models.Model):
# name = models.CharField(max_length=20)
#
# # 查询方式:
# # 通过第一本书book 找出版社
# # id = Book.objects.first().publish_id
# # publish = Publish.objects.filter(id=id)[0].name
# # print(publish)

方式二:使用外键, 用db_constrain=False 字段段开连接
# 可以使用Django ORM连表查询语法
class Book(models.Model):
name = models.CharField(max_length=20)
publish = models.ForeignKey(to='Publish',db_constraint=False,null=True,on_delete=models.SET_NULL) # to_field='id' 不写会自动添加

class Publish(models.Model):
name = models.CharField(max_length=20)

# 书的出版社 (外键方式)
# print(Book.objects.first().publish.name)
# print(Book.objects.filter(pk=1).values('publish__name'))

断开关联--- 多对多自动创建关系表

# 断开关联(db_constraint属性)的多对多自动创建关系表 (book(外键) and author)
# 断开后依然支持Django ORMlianiao 查询语法
# 当新表中无需新加额外字段时, 可以自动创建
class MyBook(models.Model):
name = models.CharField(max_length=20)
# 这里会产生第三张表
book_author = models.ManyToManyField(to='MyAuthor',db_constraint=False)

class MyAuthor(models.Model):
name = models.CharField(max_length=20)

# # 查询方法
# # 多对多(自动创建第三张表): 书的作者
# b1 = MyBook.objects.first()
# # b1.book_author 这个是关系表
# for author in b1.book_author.all():
# print(author.name)

# print(MyBook.objects.filter(pk=1).values('book_author__name'))

断开关联 --- 多对多手动创建关系表

# 手动创建关系表的原因: 可以拥有自身字段,可以通过关系表类名直接获取第三张表

# 手动创建关系表可以让关系表可以拥有更多的自身的字段,同时通过关系表类名可以直接获取第三张表
'''
# ****
# 1、和自动建立关系表类似,依然支持Django ORM连表查询语法(多对多借助关系表连表查询)
class Book(models.Model):
name = models.CharField(max_length=20)

class Author(models.Model):
name = models.CharField(max_length=20)

class Book_Author(models.Model):
book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL, db_constraint=False)
author = models.ForeignKey(to='Author', null=True, on_delete=models.SET_NULL, db_constraint=False)
time = models.DateField()
'''

'''
# ****
2、手动创建关系表,在关系表中用ForeignKey方式支持基于外键关系表的ORM连表查询,同时明确ManyToManyField字段,所以也支持ORM正向方向连表查询
-- db_constraint=False断开关联可以在ForeignKey或ManyToManyField任意一方完成
class Book(models.Model):
name = models.CharField(max_length=20)
# 明确through与through_fields,ManyToManyField才不会自动建立关系表,没有关联关系后就不能再使用db_constraint字段属性
author = models.ManyToManyField(to='Author', through='Book_Author', through_fields=('book_id', 'author_id'))

class Author(models.Model):
name = models.CharField(max_length=20)

class Book_Author(models.Model):
book = models.ForeignKey(to="Book", null=True, on_delete=models.SET_NULL, db_constraint=False)
author = models.ForeignKey(to='Author', null=True, on_delete=models.SET_NULL, db_constraint=False)
time = models.DateField()
'''
# 总结:手动创建第三张表,第三张表的增删改就采用关系表类名衍生的create|delete|update,就不再拥有add|clear|remove|set(因为关系表拥有自己的字段,这些方法无法直接操作这些字段)

到此这篇关于Django分组聚合查询实例分享的文章就介绍到这了,更多相关Django分组聚合查询内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
PyQt5每天必学之日历控件QCalendarWidget
Apr 19 Python
NumPy.npy与pandas DataFrame的实例讲解
Jul 09 Python
深入浅析Python中list的复制及深拷贝与浅拷贝
Sep 03 Python
详解Python传入参数的几种方法
May 16 Python
解决py2exe打包后,总是多显示一个DOS黑色窗口的问题
Jun 21 Python
python监控nginx端口和进程状态
Sep 06 Python
python 并发下载器实现方法示例
Nov 22 Python
Pycharm连接远程服务器过程图解
Apr 30 Python
Python devel安装失败问题解决方案
Jun 09 Python
opencv 图像礼帽和图像黑帽的实现
Jul 07 Python
在python中对于bool布尔值的取反操作
Dec 11 Python
Django drf请求模块源码解析
Jun 08 Python
python中sympy库求常微分方程的用法
Apr 28 #Python
tensorflow2.0的函数签名与图结构(推荐)
Apr 28 #Python
Python startswith()和endswith() 方法原理解析
Apr 28 #Python
Python如何将函数值赋给变量
Apr 28 #Python
Python多线程thread及模块使用实例
Apr 28 #Python
Python基于模块Paramiko实现SSHv2协议
Apr 28 #Python
Python内置函数locals和globals对比
Apr 28 #Python
You might like
支持数组的ADDSLASHES的php函数
2010/02/16 PHP
ThinkPHP模板范围判断输出In标签与Range标签用法详解
2014/06/30 PHP
laravel 验证错误信息到 blade模板的方法
2019/09/29 PHP
33个优秀的jQuery 教程分享(幻灯片、动画菜单)
2011/07/08 Javascript
JavaScript NaN和Infinity特殊值 [译]
2012/09/20 Javascript
jquery实现漂浮在网页右侧的qq在线客服插件示例
2013/05/13 Javascript
js模仿jquery的写法示例代码
2013/06/16 Javascript
jQuery实现的感应鼠标悬停图片色彩渐显效果
2015/03/03 Javascript
javascript笛卡尔积算法实现方法
2015/04/08 Javascript
浅谈JavaScript异常处理语句
2015/06/26 Javascript
Javascript基础教程之比较null和undefined值
2016/05/16 Javascript
jQuery实现图片轮播效果代码
2016/09/27 Javascript
js实现一个简单的数字时钟效果
2017/03/29 Javascript
尝试自己动手用react来写一个分页组件(小结)
2018/02/09 Javascript
vue 实现剪裁图片并上传服务器功能
2018/03/01 Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
2019/02/22 Javascript
详解使用uni-app开发微信小程序之登录模块
2019/05/09 Javascript
Node.js Windows Binary二进制文件安装方法
2019/05/16 Javascript
小程序如何构建骨架屏
2019/05/29 Javascript
Node.js系列之连接DB的方法(3)
2019/08/30 Javascript
vue实现移动端项目多行文本溢出省略
2020/07/29 Javascript
element-ui tree结构实现增删改自定义功能代码
2020/08/31 Javascript
如何正确解决VuePress本地访问出现资源报错404的问题
2020/12/03 Vue.js
python使用xauth方式登录饭否网然后发消息
2014/04/11 Python
python网络编程之读取网站根目录实例
2014/09/30 Python
简洁的十分钟Python入门教程
2015/04/03 Python
浅析AST抽象语法树及Python代码实现
2016/06/06 Python
使用Anaconda3建立虚拟独立的python2.7环境方法
2018/06/11 Python
在python中以相同顺序shuffle两个list的方法
2018/12/13 Python
python调用c++返回带成员指针的类指针实例
2019/12/12 Python
英国珠宝网站Argento: PANDORA、Olivia Burton和Nomination等
2020/05/08 全球购物
物流专业大学生的自我鉴定
2013/11/13 职场文书
医药代表个人的求职信分享
2013/12/08 职场文书
旅游专业职业生涯规划范文
2014/01/13 职场文书
中秋节活动总结
2014/08/29 职场文书
《画家和牧童》教学反思
2016/02/17 职场文书