正反向查询进阶操作
接上篇随笔的表做正反向查询的进阶操作
1. 查询主键为1 的书籍对应的出版社名称及书名
res = models. Publish. objects. filter ( book__pk= 1 ) . values( 'name' , 'book__title' )
print ( res)
2. 查询主键为2 的书籍对应的作者姓名及书名
res = models. Author. objects. filter ( book__pk= 2 ) . values( 'name' , 'book__title' )
print ( res)
3. 查询curry的作者的地址
res = models. AuthorDetail. objects. filter ( author__name= 'curry' ) . values( 'addr' )
print ( res)
4. 查询内蒙古出版社出版的书籍名称和价格
res = models. Book. objects. filter ( publish__name= '内蒙古出版社' ) . values( 'title' , 'price' )
print ( res)
5. 查询curry写过的书的名称和日期
res = models. Book. objects. filter ( authors__name= 'curry' ) . values( 'title' , 'authors__book__publish_time' )
print ( res)
6. 查询电话是110 的作者姓名和年龄
res = models. Author. objects. filter ( author_detail__addr= '内蒙古' ) . values( 'name' , 'age' )
print ( res)
7. 查询主键为1 的书籍对应的作者地址
res = models. AuthorDetail. objects. filter ( author__book__pk= 1 ) . values( 'addr' )
print ( res)
聚合查询
聚合函数
作用
max
最大值
min
最小值
sum
求和
avg
平均值
count
计数
'''聚合查询 先导入模块'''
from django. db. models import Max, Min, Sum, Avg, Count
单纯的使用聚合函数而不是在分组之后 要用关键字aggregate 分组之后不用
'''聚合查询'''
from django. db. models import Max, Min, Sum, Avg, Count
res = models. Book. objects. aggregate( Max( 'price' ) , Min( 'price' ) , Sum( 'price' ) , Avg( 'price' ) , Count( 'pk' ) )
print ( res)
分组查询
"""
分组有一个特性 默认只能够直接获取分组的字段 其他字段需要使用方法
我们也可以忽略掉该特性 将sql_mode中only_full_group_by配置移除即可
"""
'''分组查询'''
res = models. Book. objects. annotate( author_num= Count( 'authors__pk' ) ) . values( 'title' , 'author_num' )
print ( res)
res1 = models. Book. objects. values( 'publish_id' ) . annotate( book_num= Count( 'pk' ) ) . values( 'publish_id' , 'book_num' )
print ( res1)
"""
1.按照整条数据分组
models.Book.objects.annotate() 按照一条条书籍记录分组
2.按照表中某个字段分组()
models.Book.objects.values('title').annotate() 按照annotate之前values括号中指定的字段分组
"""
'''filter在annotate前面则是where 在annotate后面则是having'''
res = models. Author. objects. annotate( book_sum_price= Sum( 'book__price' ) ) . values( 'name' )
print ( res)
F与Q查询
'''F查询:查询条件不是自定义的而是来自于表中其他字段'''
from django. db. models import F
res = models. Book. objects. filter ( storage_num__gt= F( 'sale_num' ) )
models. Book. objects. update( price= F( 'price' ) + 1000 )
models. Book. objects. filter ( pk= 5 ) . update( title= F( 'title' ) + '爆款' )
from django. db. models. functions import Concat
from django. db. models import Value
ret3 = models. Book. objects. filter ( pk= 5 ) . update( title= Concat( F( 'title' ) , Value( '爆款' ) ) )
'''Q查询:可以改变Filter括号内多个条件之间的逻辑运算符 还可以将查询条件的字段改为字符串形式'''
from django. db. models import Q
'''Q查询:将查询条件的字段改为字符串形式'''
print ( res)
事务操作
事务:
一般是指要做的或所做的事情,而且事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所做的所有更改都会被撤销。
事务的四大特性:
ACID:
原子性:
一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做
一致性:
事务必须是数据库从一个一致性状态变成另一个一致性状态。一致性 与原子性是密切相关的
隔离性:
一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据,对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰
持久性:
持久性也称永久性,指一个事务一旦提交,他对数据库中的数据的改变就应该是永久性的,接下来的其他操作或故障不应该对其有任何影响。
MySQL中开启事务
start transaction
事务的回滚
rollback
事务的确认
commi
from django. db import transaction
try :
with transaction. atomic( ) :
pass
except Exception as e:
print ( e)
模型层常见字段及参数
AutoField( Field)
- int 自增列,必须填入参数 primary_key= True
BigAutoField( AutoField)
- bigint自增列,必须填入参数 primary_key= True
注:当model中如果没有自增列,则自动会创建一个列名为id 的列
from django. db import models
class UserInfo ( models. Model) :
username = models. CharField( max_length= 32 )
class Group ( models. Model) :
nid = models. AutoField( primary_key= True )
name = models. CharField( max_length= 32 )
SmallIntegerField( IntegerField) :
- 小整数 - 32768 ~ 32767
PositiveSmallIntegerField( PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField( Field)
- 整数列( 有符号的) - 2147483648 ~ 2147483647
PositiveIntegerField( PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647
BigIntegerField( IntegerField) :
- 长整型( 有符号的) - 9223372036854775808 ~ 9223372036854775807
BooleanField( Field)
- 布尔值类型
NullBooleanField( Field) :
- 可以为空的布尔值
CharField( Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度
TextField( Field)
- 文本类型
EmailField( CharField) :
- 字符串类型,Django Admin以及ModelForm中提供验证机制
IPAddressField( Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
GenericIPAddressField( Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both' , "ipv4" , "ipv6"
unpack_ipv4, 如果指定为True ,则输入: : ffff: 192.0 .2 .1 时候,可解析为192.0 .2 .1 ,开启此功能,需要protocol= "both"
URLField( CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField( CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符( 减号)
CommaSeparatedIntegerField( CharField)
- 字符串类型,格式必须为逗号分割的数字
UUIDField( Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField( Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match = None , 正则匹配
recursive= False , 递归下面的文件夹
allow_files= True , 允许文件
allow_folders= False , 允许文件夹
FileField( Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django. core. files. storage. FileSystemStorage
ImageField( FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django. core. files. storage. FileSystemStorage
width_field= None , 上传图片的高度保存的数据库字段名( 字符串)
height_field= None 上传图片的宽度保存的数据库字段名( 字符串)
DateTimeField( DateField)
- 日期+ 时间格式 YYYY- MM- DD HH: MM[ : ss[ . uuuuuu] ] [ TZ]
DateField( DateTimeCheckMixin, Field)
- 日期格式 YYYY- MM- DD
TimeField( DateTimeCheckMixin, Field)
- 时间格式 HH: MM[ : ss[ . uuuuuu] ]
DurationField( Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime. timedelta类型
FloatField( Field)
- 浮点型
DecimalField( Field)
- 10 进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
BinaryField( Field)
- 二进制类型
ORM字段与MySQL字段对应关系
对应关系:
'AutoField' : 'integer AUTO_INCREMENT' ,
'BigAutoField' : 'bigint AUTO_INCREMENT' ,
'BinaryField' : 'longblob' ,
'BooleanField' : 'bool' ,
'CharField' : 'varchar(%(max_length)s)' ,
'CommaSeparatedIntegerField' : 'varchar(%(max_length)s)' ,
'DateField' : 'date' ,
'DateTimeField' : 'datetime' ,
'DecimalField' : 'numeric(%(max_digits)s, % (decimal_places)s)' ,
'DurationField' : 'bigint' ,
'FileField' : 'varchar(%(max_length)s)' ,
'FilePathField' : 'varchar(%(max_length)s)' ,
'FloatField' : 'double precision' ,
'IntegerField' : 'integer' ,
'BigIntegerField' : 'bigint' ,
'IPAddressField' : 'char(15)' ,
'GenericIPAddressField' : 'char(39)' ,
'NullBooleanField' : 'bool' ,
'OneToOneField' : 'integer' ,
'PositiveIntegerField' : 'integer UNSIGNED' ,
'PositiveSmallIntegerField' : 'smallint UNSIGNED' ,
'SlugField' : 'varchar(%(max_length)s)' ,
'SmallIntegerField' : 'smallint' ,
'TextField' : 'longtext' ,
'TimeField' : 'time' ,
'UUIDField' : 'char(32)' ,
多对多三种创建方式
1. 自动创建
authors = models. ManyToManyField( to= 'Author' )
优点: 第三张表自动创建
缺点: 第三张表扩展性差
2. 手动创建
class Book ( models. Model) :
pass
class Author ( models. Model) :
pass
class Book2Author ( models. Model) :
book_id = models. ForeignKey( to= "Book" )
author_id = models. ForeignKey( to= "Author" )
优点: 第三张表扩展性强
缺点: 无法使用正反向查询以及多对多四个方法
3. 半自动创建
class Book ( models. Model) :
authors = models. ManyToManyField( to= 'Author' ,
through= 'Book2Author'
through_fields= ( 'book_id' , 'author_id' )
)
class Author ( models. Model) :
pass
class Book2Author ( models. Model) :
book_id = models. ForeignKey( to= "Book" )
author_id = models. ForeignKey( to= "Author" )
优点: 扩展性强并且支持正反向查询
缺点: 无法使用多对多四个方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了