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 相关文章推荐
python实现目录树生成示例
Mar 28 Python
python编写网页爬虫脚本并实现APScheduler调度
Jul 28 Python
Python创建xml文件示例
Mar 22 Python
浅谈python新式类和旧式类区别
Apr 26 Python
python实现在cmd窗口显示彩色文字
Jun 24 Python
pymysql 开启调试模式的实现
Sep 24 Python
python3连接kafka模块pykafka生产者简单封装代码
Dec 23 Python
python如何通过twisted搭建socket服务
Feb 03 Python
python函数调用,循环,列表复制实例
May 03 Python
python批量修改交换机密码的示例
Sep 22 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
Dec 13 Python
Python访问Redis的详细操作
Jun 26 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
基于php设计模式中单例模式的应用分析
2013/05/15 PHP
Smarty中常用变量操作符汇总
2014/10/27 PHP
Yii中Model(模型)的创建及使用方法
2015/12/28 PHP
PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析
2017/02/04 PHP
通过下拉框的值来确定输入框是否可以为空的代码
2011/10/18 Javascript
上传的js验证(图片/文件的扩展名)
2013/04/25 Javascript
jQuery中RadioButtonList的功能及用法实例介绍
2013/08/23 Javascript
js密码强度校验
2015/11/10 Javascript
基于JavaScript代码实现pc与手机之间的跳转
2015/12/23 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
前端程序员必须知道的高性能Javascript知识
2016/08/24 Javascript
jQuery实现输入框邮箱内容自动补全与上下翻动显示效果【附demo源码下载】
2016/09/20 Javascript
Javascript中的getter和setter初识
2017/08/17 Javascript
nodejs 图解express+supervisor+ejs的用法(推荐)
2017/09/08 NodeJs
vue+element创建动态的form表单及动态生成表格的行和列
2019/05/20 Javascript
vue 组件内获取actions的response方式
2019/11/08 Javascript
JavaScript如何处理移动端拍摄图片旋转问题
2019/11/16 Javascript
js回调函数仿360开机
2019/12/26 Javascript
file-loader打包图片文件时路径错误输出为[object-module]的解决方法
2020/01/03 Javascript
JS 5种遍历对象的方式
2020/06/16 Javascript
js实现tab栏切换效果
2020/08/02 Javascript
[44:40]2018DOTA2亚洲邀请赛3月30日 小组赛A组Liquid VS OG
2018/03/31 DOTA
Python中的MongoDB基本操作:连接、查询实例
2015/02/13 Python
python圣诞树编写实例详解
2020/02/13 Python
解决jupyter notebook打不开无反应 浏览器未启动的问题
2020/04/10 Python
Python logging日志模块 配置文件方式
2020/07/12 Python
CSS3——齿轮转动关键代码
2013/05/02 HTML / CSS
使用HTML5 Canvas API中的clip()方法裁剪区域图像
2016/03/25 HTML / CSS
大学生村官事迹材料
2014/01/21 职场文书
年度献血先进个人事迹材料
2014/02/14 职场文书
马智宇婚礼主持词
2014/03/22 职场文书
初三学习计划书范文
2014/04/30 职场文书
货物运输服务质量承诺书
2014/05/29 职场文书
甲午风云观后感
2015/06/02 职场文书
90行Python代码开发个人云盘应用
2021/04/20 Python
CSS3实现列表无限滚动/轮播效果
2021/06/23 HTML / CSS