聚合函数

名称 作用
Max() 最大值
Min() 最小值
Sum() 求和
Count() 计数
Avg() 平均值

关键字: aggregate

聚合查询通常都是配合分组一起使用的

关于数据库的模块

基本上都在django.db.models里面
如果上述没有那么应该在django.db里面
# 要导入模块
from django.db.models import Max, Min, Sum, Count, Avg
# 1.所有书的平均价格
res = models.Book.objects.aggregate(Avg('price'))
print(res) # {'price__avg': 311.262}
# 2.使用所有的功能
res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Count('id'), Avg('price'))
print(res)

分组查询

关键字: annotate

格式:
# 按表分组
models.表名.objects.annotate() # models后面跟什么就按什么分组
# 按字段分组
models.表名.objects.values('字段').annotate() # annotate前有values就按指定字段分组 没有就按表名分组

用法

# 1.统计每一本书的作者的个数j书名
res = models.Book.objects.annotate(author_num=Count('author')).values('title', 'author_num')
print(res)

# 2.统计每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price')
print(res)

# 3.统计不止一个作者的图书
res = models.Book.objects.annotate(author_num=Count('author')).filter(author_num__gt=1).values('title', 'author_num')
print(res)

# 4.查询每个作者出的书的总价格
res = models.Author.objects.annotate(total_price=Sum('book__price')).values('name', 'total_price')
print(res)

按年月分组

id       content               create_time                   month  # 这个字段是django虚拟出的字段
1 111 2020-11-11 2020-11
2 222 2020-11-12 2020-11
3 333 2020-11-13 2020-11
4 444 2020-11-14 2020-11
5 555 2020-11-15 2020-11
"""
django官网提供的一个orm语法
from django.db.models.functions import TruncMonth
-官方提供
from django.db.models.functions import TruncMonth
Sales.objects
.annotate(month=TruncMonth('timestamp')) # Truncate to month and add to select list
.values('month') # Group By month
.annotate(c=Count('id')) # Select the count of the grouping
.values('month', 'c') # (might be redundant, haven't tested) select month and count eg:
# 按时间年月分组取出文章个数
date_list = models.Article.objects
.annotate(month=TruncMonth('create_time')) # 这行是产生month虚拟字段
.values('month').annotate(article_num=Count('pk')) # 这行是按month分组并计算数量
.values_list('month', 'article_num') # 取年月字段 和对应的数量

报错处理

如果出现错误,分组后查不出来 ,有可能是因为严格模式的原因
要去修改数据库的严格模式
分组之后默认只能获取到分组的依据 组内其他字段都无法直接获取了
严格模式
ONLY_FULL_GROUP_BY

F与Q查询

F查询

作用: 能够帮助你直接获取到表中的某个字段对应的数据

from django.db.models import F
# 1.查询卖出数大于库存数的书籍
from django.db.models import F, Q
res = models.Book.objects.filter(maichu__gt=F('kucun'))
print(res)

# 2.将所有的书的价格提高50块
res = models.Book.objects.update(price=F('price')+50)

F是不能直接操作字符串拼接的
需要导入另外两个模块
from django.db.models.functions import Concat
from django.db.models import Value
就可以使用了

from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.update(title=Concat(F('title'), Value('爆款')))

Q查询

filter() 等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象

作用: 能够在filter里添加or关系或者not关系

# 1.查询卖出数大于100或者价格小于600的书籍
# 先导入模块
from django.db.models import Q
res = models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600))
res1 = models.Book.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600))
print(res)
print(res1)

Q的高阶用法

作用: 能够将查询条件的左边也变成字符串的形式

用于: 能让用户自己选择检索功能

q = Q()
q.children.append(('maichu__gt', 100))
q.children.append(('kucun', 600))
# 这是默认关系还是and 要改成or
q.connector = 'or'
res = models.Book.objects.filter(q)
print(res)

django中如何开启事务

"""
事务
ACID
原子性
不可分割的最小单位
一致性
跟原子性是相辅相成
隔离性
事务之间互相不干扰
持久性
事务一旦确认永久生效 事务的回滚
rollback
事务的确认
commit
"""
# 目前你只需要掌握Django中如何简单的开启事务
# 事务
from django.db import transaction
try: # 异常捕获也可以不加
with transaction.atomic():
# sql1
# sql2
...
# 在with代码快内书写的所有orm操作都是属于同一个事务
except Exception as e:
print(e)
print('执行其他操作')

orm中常用字段及参数

AutoField
主键字段 primary_key=True CharField varchar
verbose_name 字段的注释
max_length 长度 IntegerField int
BigIntegerField bigint DecimalField
max_digits=8 # 代表的意思是222222.22
decimal_places=2 EmailFiled varchar(254) DateField date
DateTimeField datetime
auto_now:每次修改数据的时候都会自动更新当前时间
auto_now_add:只在创建数据的时候记录创建时间后续不会自动修改了 BooleanField(Field) - 布尔值类型
该字段传布尔值(False/True) 数据库里面存0/1 TextField(Field) - 文本类型
该字段可以用来存大段内容(文章、博客...) 没有字数限制
后面的bbs作业 文章字段用的就是TextField FileField(Field) - 字符类型
upload_to = "/data"
给该字段传一个文件对象,会自动将文件保存到/data目录下然后将文件路径保存到数据库中
/data/a.txt
后面bbs作业也会涉及 # 更多字段
直接参考博客:https://www.cnblogs.com/Dominic-Ji/p/9203990.html # django除了给你提供了很多字段类型之外 还支持你自定义字段
class MyCharField(models.Field):
def __init__(self,max_length,*args,**kwargs):
self.max_length = max_length
# 调用父类的init方法
super().__init__(max_length=max_length,*args,**kwargs) # 一定要是关键字的形式传入 def db_type(self, connection):
"""
返回真正的数据类型及各种约束条件
:param connection:
:return:
"""
return 'char(%s)'%self.max_length

# 外键字段及参数
unique=True
ForeignKey(unique=True) === OneToOneField()
# 你在用前面字段创建一对一 orm会有一个提示信息 orm推荐你使用后者但是前者也能用 db_index
如果db_index=True 则代表着为此字段设置索引
(复习索引是什么) to_field
设置要关联的表的字段 默认不写关联的就是另外一张的主键字段 on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。
"""
django2.X及以上版本 需要你自己指定外键字段的级联更新级联删除
"""

数据库查询优化

orm语句的特点

惰性查询

如果你仅仅只是书写了orm语句 在后面根本没有用到该语句所查询出来的参数
那么orm会自动识别 直接不执行

res = models.Book.objects.all()
print(res) # 在注释掉打印操作的时候 不会出现SQL语句 但是执行打印操作的话就会出现SQL语句

only与defer

only

res = models.Book.objects.only('title')
for i in res:
print(i.title) # 查询only括号内的字段 不会走数据库
print(i.price) # 查询only括号内没有的字段 会重新走数据库查询 而all不需要走

defer(和only恰恰相反)

res = models.Book.objects.defer('title')
for i in res:
print(i.title) # 查询only括号内的字段 会重新走数据库查询
print(i.price) # 查询only括号内没有的字段 不会走数据库

总结:

defer与only刚好相反
defer括号内放的字段不在查询出来的对象里面 查询该字段需要重新走数据
而如果查询的是非括号内的字段 则不需要走数据库了

select_related与prefetch_related

select_related

res = models.Book.objects.select_related('publish')  # inner join 连表操作
for i in res:
print(i.publish.name)

 select_related内部直接先将book与publish连起来 然后一次性将大表里面的所有数据
全部封装给查询出来的对象
这个时候对象无论是点击book表的数据还是publish的数据都无需再走数据库查询了 select_related括号内只能放外键字段 一对多 一对一
多对多不行

prefetch_related

res = models.Book.objects.prefetch_related('publish')  # 子查询
for i in res:
print(i.publish.name) # 会比select_related查询多走一步SQL语句
prefetch_related该方法内部其实就是子查询
将子查询查询出来的所有结果也给你封装到对象中
给你的感觉好像也是一次性搞定的

总结:

这两个没有说绝对的谁比谁更好,在数据量较大的时候select_related的

连表操作可能会更慢,具体情况具体分析

ORM中聚合函数、分组查询、Django开启事务、ORM中常用字段及参数、数据库查询优化的更多相关文章

  1. Django框架(十一)—— 常用字段、参数、元信息、多对多关联关系

    目录 常用字段和参数 一.ORM字段 二.ORM参数 三.关系字段 1.ForeignKey 2.OneToOneFiled 3.ManyToManyField 四.元信息 五.多对多关联关系的三种方 ...

  2. 07 模型层 orm相关查询 F查询Q查询 django开启事务

    一.Django终端打印SQL语句 如果你想知道你对数据库进行操作时,Django内部到底是怎么执行它的sql语句时可以加下面的配置来查看 在Django项目的settings.py文件中,在最后复制 ...

  3. Django框架(十)--常用字段、参数、元信息、多对多关联关系

    一.ORM字段 # AutoField() int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列 # IntegerField() ...

  4. 在论坛中出现的比较难的sql问题:3(row_number函数 分组查询)

    原文:在论坛中出现的比较难的sql问题:3(row_number函数 分组查询) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所 ...

  5. Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)

    Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...

  6. Django聚合与分组查询中value与annotate的顺序问题

    在学习Django聚合与分组查询中,发现value与annotate的顺序不同时,查询结果大相径庭,经过一下午的研究,终于弄明白了,现在分享给大家,先上结论: 结论 value在annotate前面时 ...

  7. 第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; Select 列 into 新表;字符串函数;日期函数

    第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all;  ...

  8. Django ORM中常用字段和参数

    一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...

  9. parse_str() 函数把查询字符串解析到变量中。

    定义和用法 parse_str() 函数把查询字符串解析到变量中. 注释:如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量. 注释:php.ini 文件中的 magic_quo ...

随机推荐

  1. CentOS7 MySql数据库安装配置(单实例)

    一. 安装mysql-server 官网下载安装 # wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm # ...

  2. ZYNQ使用ymodem协议传输文件

    SDK: V2014.4 协议: Ymodem 工具: USB转UART转接线.xshell6软件 可实现各种文件传输,大小不限,只是速度很慢 参考原代码如下: /****************** ...

  3. STL基本用法的一些记录

    迭代器 (set类型)::iterator 就是迭代器 迭代器可以看成stl容器内元素的指针 set 默认从小到大排序 begin() set中最小的元素的迭代器 end() set中最大的元素的迭代 ...

  4. 12.11 Exception

    12.11exception 1.类别 检查性异常:用户错误或者问题引起的异常,此类异常程序员无法预见.例如:打开一个不存在的文件,用户输入错误(在只能输数字的地方输入汉字)...... 运行时异常: ...

  5. final, finally, finalize的区别?

    final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承.内部类要访问局部变量,局部变量必须定义成final类型.finally是异常处理语句结构的一部分,表示总是执行.fin ...

  6. park和unpark

    1 介绍 LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport提供的两个主要方法就是park和unpark. park译为&quo ...

  7. leedcode_13 罗马数字转整数

    罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1 .12 ...

  8. python中类变量和实例变量的区别

    类变量:可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的).实例变量:实例化之后,每个实例单独拥有的变量. class student(): age = 0 name = 'stu ...

  9. 3_一起燃烧卡路里/科学减肥(1)_系统分析实例_数学建模部分_Matlab/Simulink

     

  10. Centos7 离线安装 KVM,并安装 Csr1000v

    最近需要在客户环境搭建 csr1000v,客户环境不能联网,同时使用 kvm 管理.所以需要离线安装 kvm,在利用 kvm 安装 csr100v ,中间遇到不少坑,现记录如下. 所有安装步骤是在 r ...