聚合函数

名称 作用
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. 分布式锁用Redis与Zookeeper的使用

    为什么用分布式锁?   在讨论这个问题之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会 ...

  2. 说说UI自动化中的PO模式

    PO模式,全称PageObject模式,即页面对象模式.将页面定位与业务操作分离. po模式有以下几个优点: 1.易读性好 2.扩展性高 3.复用性强 4.维护性好 5.代码冗余率低 了解了po模式及 ...

  3. 浅析MySQL恶意服务器读取文件原理

    前言 注:本文不涉及对MySQL协议报文研究,仅讲解原理,并且做部分演示. 搭建MySQL恶意服务器读取文件这件事,虽然直接利用门槛较高,但是由于在网上看到了一种比较新颖的利用方式(利用社会工程学引诱 ...

  4. Java 框架、库和软件的精选列表(awesome java)

    原创翻译,原始链接 本文为awesome系列中的awesome java Awesome Java Java 框架.库和软件的精选列表 项目 Bean映射 简化 bean 映射的框架 dOOv - 为 ...

  5. 半吊子菜鸟学Web开发5 -- PHP开发环境配置

    本文参考自:http://blog.csdn.net/angon823/article/details/54415855 Ubuntu16.04 默认 apt-get install apache2  ...

  6. 为什么要配置JDK环境变量?

    1. PATH环境变量.作用是指定命令搜索路径,在shell下面执行命令时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序.我们需要把 jdk安装目录下的bin目录增加到现有的PATH ...

  7. 什么是通知(Advice)?

    特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice.Spring AOP 使用一 个 Advice 作为拦截器,在 JoinPoint "周围"维护一系列 ...

  8. 不同版本的 Spring Framework 有哪些主要功能?

    Version Feature Spring 2.5 发布于 2007 年.这是第一个支持注解的版本. Spring 3.0 发布于 2009 年.它完全利用了 Java5 中的改进,并为 JEE6 ...

  9. 一个 Spring 的应用看起来象什么?

    一个定义了一些功能的接口.这实现包括属性,它的 Setter , getter 方法和函数等.Spring AOP.Spring 的 XML 配置文件.使用以上功能的客户端程序.

  10. 学习saltstack (五)

    Saltstack介绍 Salt三种运行方式 1.local本地运行2.Master/Minion3.Salt ssh Salt的三大功能 a.远程执行b.配置管理(状态管理)c.云管理:阿里云,aw ...