day65 django进阶(1)
一、聚合查询与分组查询
1 聚合查询(aggregate)
ps:通常情况下聚合查询都是配合分组查询一起使用的
# django中与数据库相关的模块基本都在django.db.models里或者在django.db里
from django.db.models import Max,Min,Sum,Count,Avg
# 查询所有书的平均价格
res = models.Book.objects.aggregate(Avg('price'))
# 也可以联合使用
res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('pk'),Avg('price'))
2 分组查询(annotate)
分组在mysql类似于group by,分组之后默认只能拿到分组的数据。
如果报错,可能是严格模式的问题,设置一下 ONLY_FULL_GROUP_BY即可
# 统计每一个作者写了几本书
obj = models.Author.objects.annotate(count_book=Count('book')).values('name','count_book')
# 统计每本书有几个作者
obj = models.Book.objects.annotate(author_count=Count('authors')).values('title','author_count')
# 统计每个出版社最便宜的书
obj = models.Publish.objects.annotate(cheaper_book=Min('book__price')).values('name','cheaper_book')
# 统计作者不止一个的书籍
obj = models.Book.objects.annotate(author_num = Count('authors')).filter(author_num__gt=1).values('title','author_num')
# 统计每个作者写的书的总价格
obj = models.Author.objects.annotate(sum_price = Sum('book__price')).values('name','sum_price')
上述查询对应的mysql语句
# 查询每个出版社最便宜的书
SELECT
app01_publish.NAME,
min( price )
FROM
app01_publish
JOIN app01_book ON app01_publish.id = app01_book.publish_id
GROUP BY
publish_id
# 统计每个作者有几本书
SELECT
app01_author.NAME,
COUNT( app01_book_authors.book_id )
FROM
app01_author
JOIN app01_book_authors ON app01_author.id = app01_book_authors.author_id
GROUP BY
app01_author.id
# 统计每本书有几个作者
SELECT
app01_book.title,
count( app01_book_authors.author_id ) AS count_authors
FROM
app01_book
JOIN app01_book_authors ON app01_book.id = app01_book_authors.book_id
GROUP BY
app01_book.id
# 查询作者数大于一的书籍
SELECT
title,
count( app01_book_authors.author_id ) AS author_num
FROM
app01_book
JOIN app01_book_authors ON app01_book.id = app01_book_authors.book_id
GROUP BY
app01_book.id
HAVING
count( app01_book_authors.author_id )>1
# 统计每个作者的书的总价格
SELECT
app01_author.NAME,
sum( app01_book.price )
FROM
app01_author
JOIN app01_book_authors ON app01_author.id = app01_book_authors.author_id
JOIN app01_book ON app01_book_authors.book_id = app01_book.id
GROUP BY
app01_author.id
二、F与Q查询
1 F查询的三个功能
1.1 能帮助我们直接获取到表中某个字段对应的数据
from django.db.models import F
# 1 查寻卖出数大于库存数的书籍
models.Book.objects.filter(maichu__gt=F('kucun'))
1.2 获取一个整形字段的数据进行运算
models.Book.objects.filter.update(price=F('price')+500)
1.3 获取一个字符串字段进行拼接
from django.db.models.functions import Concat
from django.db.models import Value
models.Book.object.update(title=Concat(F('title'),Value('爆款')))
# 如果不按照这种方法直接用数字那样加减的话,所有名称会都变成空白
2 Q查询
2.1 修改查询之间的关系
from django.db.models import Q
# 默认情况下filter内部的条件用,隔开,逗号表示and关系,如果要修改这个关系只能用Q查询来做
models.Book.objects.filter(id__gt=1, price__lt=2000)
# 在Q查询中逗号也是表示为and关系
models.Book.objects.filter(Q(id__gt=1), Q(price__lt=2000))
# 查询id>2或者价格<2000的书籍 |为or
models.Book.object.filter(Q(id__gt=2)|Q(price__lt=2000))
# 查询id不大于3或者价格小于600的书籍 ~为not
models.Book.objects.filter(~Q(id__gt=3)|Q(price__lt=600))
2.2 Q查询的高阶用法
q = Q() # 实例化一个Q对象
q.connector = 'or' # 设置默认关系为or,不设置的话为and
q.children.append(('maichu__gt',100)) # 添加查询条件,第一个为字段查询条件,第二个为参数
q.children.append(('price__lt',600))
res = models.Book.objects.filter(q)
print(res)
三、事务
"""
事务
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中常用的字段及参数
1 基本字段
# 一些全都有的参数,verbose_name 字段的注释,defalut 默认值,null=True/False 是否允许为空
# 主键字段
AutoField(primary_key=True)
# 字符字段 varchar(最大长度255)
CharField(max_length=32)
# 整形字段 int
IntegerField()
# 长整形 bigint
BigIntegerField()
# 浮点型 float
DecimalField(max_digts=8(最大长度,包括小数),decimal_places=2(小数部分长度))
# 邮箱 varchar(254)
EmailFiled
# 日期类型 date
DateField
# 精确日期类型 datetime
DateTimeField
# 日期类型的参数:
# auto_now:每次修改数据的时候都会自动更新当前时间
# auto_now_add:只在创建数据的时候记录创建时间,后续不会自动修改
# 布尔值
BooleanField # 数据里面存0/1
# 文本类型
TextField # 可以存放大量文本内容,没有字数限制
# 文件类型 -字符类型
FileField(upload_to='文件保存的路径')
# 会给该字段穿一个文件对象,把文件本身自动保存到路径下,这个字段内保存的是文件路径
# 更多字段
直接参考博客:https://www.cnblogs.com/Dominic-Ji/p/9203990.html
2 自定义字段
# 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
# 自定义字段使用
myfield = MyCharField(max_length=16,null=True)
3 外键字段及参数
# 当外键字段唯一的时候就成了一对一关系
ForeignKey(unique=True) === OneToOneField()
# db_index = True 代表这个字段设置为索引
# to_field 设置要关联的表的字段,默认不写就是关联另外一张的主键字段
# on_delete 当删除关联表的数据时,对当前表关联的行为
# django2.X以上需要指定级联更新和级联删除
五、数据库查询优化
orm语句的特点:惰性查询,如果只写的orm语句,后续没有使用,orm会自动识别,直接不执行
res = models.Book.object.all() # 这个语句不会执行因为这一行还没用到
print(res) # 用到了才会去执行上面代码
1 only与defer
# 普通取一个字段
res = models.Book.object.values('title').first()
print(res.get('title'))
# values会限定只取固定字段,取没有的就是空,only更加灵活
# only取一个字段
res = models.Book.objects.only('title').first()
print(res.title)
# only的限定,相当于只从数据库里读取了很小一部分的数据,这里的res=取出来的title,优化了我们查询的速度,如果我们点其他字段就会重新到数据库中去查
# defer与only恰恰相反,除了得到的返回值还是括号内的字段结果
2 select_related与prefetch_related
# 这种优化作用于跨表查询
res = models.Book.objects.all()
for obj in res:
print(obj.publish.name) # 这里没循环一次都要走一次数据库查询
res = models.Book.objects.select_related('authors')
# select_related默认内部会先把book和publish连起来,然后一次性把大表里的所有数据全都分装起来给对象,这个时候无论是点击book表还是publish表都不会走数据库查询了,相当于mysql中的join
# 特别的是,select_related括号内只能放外键字段 一对多,一对一
# 多对多不行
# prefetch_related内部就是子查询,把查询出来的结果全都封装给对象
res = models.Book.objects.prefetch_related('publish')
day65 django进阶(1)的更多相关文章
- Python之路,Day16 - Django 进阶
Python之路,Day16 - Django 进阶 本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...
- django进阶补充
前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...
- django进阶-3
先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...
- django进阶-4
前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...
- Django进阶篇【1】
注:本篇是Django进阶篇章,适合人群:有Django基础,关于Django基础篇,将在下一章节中补充! 首先我们一起了解下Django整个请求生命周期: Django 请求流程,生命周期: 路由部 ...
- Django进阶知识
drf学习之Django进阶点 一.Django migrations原理 1.makemigrattions: 相当于在每个app下的migrations文件夹下生成一个py脚本文件用于创建表或则修 ...
- django进阶-查询(适合GET4以上人群阅读)
前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...
- django进阶-modelform&admin action
先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...
- django进阶-小实例
前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...
随机推荐
- FastJson将Java对象转换成json
确保环境依赖都配置好! 1.在pom.xml导入依赖 <dependency> <groupId>com.alibaba</groupId> <artifac ...
- Zookeeper——Watcher原理详解
文章目录 引言 正文 一.如何注册监听 二.如何触发监听事件 三.事件类型有哪些 四.Watcher可以被无限次触发么?为什么要这么设计? 五.Watcher实现原理 1. 客服端发送请求 a. 初始 ...
- [置顶] linux中fork()函数详解(原创!!实例讲解)
分类: 计算机系统 linux2010-06-01 23:35 60721人阅读 评论(105) 收藏 举报 linux2010存储 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源 ...
- DNS bind使用
概念介绍 DNS的分类 主DNS:配置管理,不提供服务,只用来编辑配置信息,给从DNS提供同步数据 从DNS:从主DNS上同步数据信息,对外提供服务 缓存DNS:在主DNS和从DNS之间,用来递归解析 ...
- Spark3.0分布,Structured Streaming UI登场
近日,在Spark开源十周年之际,Spark3.0发布了,这个版本大家也是期盼已久.登录Spark官网,最新的版本已经是3.0.而且不出意外,对于Structured Streaming进行了再一次的 ...
- JSON类库Jackson优雅序列化Java枚举类
1. 前言 在Java开发中我们为了避免过多的魔法值,使用枚举类来封装一些静态的状态代码.但是在将这些枚举的意思正确而全面的返回给前端却并不是那么顺利,我们通常会使用Jackson类库序列化对象为JS ...
- 1、struct2第一个项目登陆流程
这些jar包的作用:第一个日志记录 第二个 使用freemarker制作页面,freemarker和jsp一样都是页面操作的 ognl是struct2提供的向el标签设置的包 struct2-core ...
- 使用 Masstransit中的 Request/Response 与 Courier 功能实现最终一致性
简介 目前的.net 生态中,最终一致性组件的选择一直是一个问题.本地事务表(cap)需要在每个服务的数据库中插入消息表,而且做不了此类事务 比如:创建订单需要 余额满足+库存满足,库存和余额处于两个 ...
- 关于SPSS Modeler18 提示:用于定义的观测值的字段的值无效
今天在做实验的时候,按照实验步骤严格设置了参数,当运行节点的时候,一直提示:用于定义的观测值的字段的值无效,如下图 我把我的流文件发给同学,同学的机器上是可以运行的,但是我的不行,不知道什么原因,有知 ...
- mac下创建安卓应用 hello-world
教程 https://www.jianshu.com/p/bf77cb5ce70b 需要注意的地方 jdk目录查找 jdk目录拷贝到tool目录下面(jdk可以拷贝,没有其他牵扯) https://w ...