聚合函数

名称 作用
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. ArcMap问题及解决方案

    1.导出的矢量文件dbf格式用Excel打开后全是乱码怎么解决? 该类问题的部分解决方案是将数据用[表转Execl ] 工具转出来 能根本解决的方法是修改注册表 详细解决方案是: 乱码解决办法:①快捷 ...

  2. Mybatis数据库分页

    使用limit分页(sql语句) SELECT * FROM user limit 0,2 #从第0个开始查,查2个 使用Mybatis实现分页,核心还是sql(map) <select id= ...

  3. UIautomatorviewer连接设备报错Unexpected error while obtaining UI hierarchy

    先来看下现象哈,点击sdk/tools下uiautomatorviever.bat,点击连接设备的图标,本以为就这么简单,那你就错了: 是不是看到这个瞬间心情就不好了,那么我们该怎么解决这个问题呢,归 ...

  4. CTF--这好像不是文件上传

    打开题目F12看到一个被注释的跳转. 访问可以知道是一个文件包含 经过测试,该文件禁止了input.data关键字.并禁止了phar://协议. 使用php://filter读取题目源码得到 http ...

  5. DDOS流量攻击

    0x01 环境 包含2台主机 attact 作为攻击方,使用Centos7.2 windows_server ,用于被攻击,同时抓包分析流量 ,任意版本均可.安装wireshark,用于抓包 0x02 ...

  6. phpcms手工注入教程

    目标服务器(靶机):192.168.1.27 目标网站:http://192.168.1.27:8083 步骤: 一.靶机操作 1.进入靶机,查看IP地址: 开始-运行,输入cmd回车,出现命令行窗口 ...

  7. linux鸟哥学习笔记

    Linux学习笔记 Linux档案权限和目录配置 目录如果没有x权限,则无法进入该目录 改变文件和属性 chgrp: 改变档案所属的群组 chown:改变档案的拥有者 chmod:改变档案的权限,SU ...

  8. JAVA视频笔记(一)

    搭建pho开发环境与框架图 韩顺平 第一章: No1  关于文件以及文件夹的管理 将生成的文本文档做成详细信息的形式,显示文件修改时间以及文件大小,便于文件查看和管理,也是对于一名IT人士高效能工作的 ...

  9. Redis+Caffeine两级缓存,让访问速度纵享丝滑

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 在高性能的服务架构设计中,缓存是一个不可或缺的环节.在实际的项目中,我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中, ...

  10. 在Spring的事务体系中,事务传播特性:Required和RequiresNew有何不同?

    Required 如果当前存在一个事务,则加入当前事务.如果不存在任何事务,则创建一个新的事务.总之,要至少保证在一个事务中运行.PROPAGATION_REQUIRED通常作为默认的事务传播行为.p ...