框架基础ORM结束篇
一.聚合查询
from django.db.models import Max, Min, Sum, Avg, Count
1.聚合函数单独使用
res = models.Book.objects.aggregate(Max('price'),
Min('price'),
Sum('price'),
Avg('price'),
Count('pk')
)
{'price__max': Decimal('29999.88'), 'price__min': Decimal('134.22'), 'price__sum': Decimal('108044.19'), 'price__avg': 15434.884286, 'pk__count': 7}
# 对于没有分组的就是默认整体就是一组
Max # 统计最大值
Min # 统计最小值
Sum # 求和
Avg # 求某个字段的平均值
Count # 求某个字段的总个数
二.分组查询
1.统计每本书的作者个数
from django.db.models import Count
res = models.Book.objects.annotate(author_num=Count('authors__pk')).values('title', 'author_num')
2.统计每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price')
3.统计不止一个作者的图书
from django.db.models import Count
res=models.Book.objects.annotate(m=Count('authors__pk')).filter(m__gt=1).values('title')
4.统计每个作者出的书的总价格 res=models.Book.objects.annotate(m=Sum('price')).values('authors__name','m')
5.统计每个出版社主键值对应的书籍个数 res=models.Book.objects.values('publish_id').annotate(m=Count('pk')).values('publish__name','m')
# 对于分组用anotate,values写在annotate前则以字段分组,如果卸载annotate后则以表分组
三.F与Q查询
1.对于已有数据表再添加字段需要将字段设置default默认值或者null=Ture或者在迁移命令值直接给默认值
# F查询
from django.db.models import F
2.查询库存大于销量的书籍
res =models.Book.objects.filter(kucun__gt=F('maichu'))
3.将所有数的价格提升1000块
res=models.Book.objects.update(price=F('price')+1000)
4.将所有书的书名加上爆款后缀
from django.db.models.functions import Concat
from django.db.models import Value
res=models.Book.objects.update(name=cancat(F('title'),Value('爆款')))
# Q查询 特点就是可以支持逻辑运算符
1.查询价格大于20000或者卖出大于1000的书籍
res=models.Book.objects.filter(Q(price__gt=2000) | Q(maichu__gt=1000)) # 在Q前加上~就是加上一个not
2.Q对象的进阶用法
q_obj=Q()
q_obj.connector='or' #默认为and
q_obj.children.append(('price__gt',2000))
q_obj.children.append(('maichu__gt',1000))
res=models.Book.objects.filter(q_obj)
# 对于F查询就是筛选的条件两个都来自表中那么就要用到F查询
# 对于Q查询就是筛选条件是或者的关系就要使用到Q查询
四.ORM查询优化
1.orm查询默认都是惰性查询不用到这个他就不会去做
2.orm默认自带分页功能减轻数据库压力
3.only查询它是将括号内的字段数据全部数据封装到对象中,如果后面查询的不在括号内那么这个时候会去数据库拿
res = models.Book.objects.only('title', 'price')
for obj in res:
print(obj.title)
print(obj.price)
print(obj.publish_time)
4.defer与only用法相反感觉像not only
5.select_related和prefetch_related
res = models.Book.objects.select_related('publish')
# for obj in res:
# print(obj.title)
# print(obj.publish.name)
# print(obj.publish.addr)
select_related括号内只能传一对一和一对多字段,底层原理是连接表,然后将所有数据封装到对象中后续不再走数据库
prefetch_related底层原理是多次查询到的结果封装到数据对象中,后面查询也不会再走数据库
五.ORM常见字段
1.AutoField() # 参数primary_key=True必写如果没有这字段会子自动创建自增的主键
2.IntegerField # 整型
3.CharField # varchar类型必须提供参数max_lengh参数
4.DateField # 日期字段跟datetime.date
5.DateTimeField # 日期时间字段datetime.datedatetime
6.SmallIntegerField(IntegerField) #
7.PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) # 正小整数 0 ~ 32767
8.IntegerField(Field) # 整数列(有符号的) -2147483648 ~ 2147483647
9.PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) # 正整数 0 ~ 2147483647
10.BigIntegerField(IntegerField):# - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
11.BooleanField(Field) # 布尔值类型
12.NullBooleanField(Field) # 可以为空的布尔值
13.TextField(Field) # 文本类型
14.EmailField(CharField) # 字符串类型,Django Admin以及ModelForm中提供验证机制
15.ForeignKey # 设置一对多关系的外键
16.ManyToManyField # 创建多对多关系的外键
17.OneToOneField # 创建一对一关系的外键
六.重要参数
1.null=True # 用于设置字段可以为空
2.unique=True # 设置唯一值
3.db_index=True # 设置索引
4.default='默认值'
5.auto_now_add=True # 记录数据库创建的时间
6.auto_now=True # 每次更新数据都会更新时间
7.to # 设置关联表的表并且会自动跟主键关联
8.on_delete=models.CASCADE # 级联删除
9.db_constraint # 外键约束
七.事务操作
1.事务四大特性
原子性
一致性
独立性
持久性
2.简单操作
from django.db import transaction
try:
with transaction.atomic():
pass
except Exception:
pass
八.ORM执行原生SQL
# 方式1
from django.db import connection, connections
cursor = connection.cursor()
cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
cursor.fetchone()
# 方式2
models.UserInfo.objects.extra(
select={'newid':'select count(1) from app01_usertype where id>%s'},
select_params=[1,],
where = ['age>%s'],
params=[18,],
order_by=['-age'],
tables=['app01_usertype']
)
九.多对多三种创建方式
# 全自动(常见)
orm自动创建第三张表 但是无法扩展第三张表的字段
authors = models.ManyToManyField(to='Author')
# 全手动(使用频率最低)
优势在于第三张表完全自定义扩展性高 劣势在于无法使用外键方法和正反向
class Book(models.Model):
title = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
class Book2Author(models.Model):
book_id = models.ForeignKey(to='Book')
author_id = models.ForeignKey(to='Author')
# 半自动(常见)
正反向还可以使用 并且第三张表可以扩展 唯一的缺陷是不能用
add\set\remove\clear四个方法
class Book(models.Model):
title = models.CharField(max_length=32)
authors = models.ManyToManyField(
to='Author',
through='Book2Author', # 指定表
through_fields=('book','author') # 指定字段
)
class Author(models.Model):
name = models.CharField(max_length=32)
'''多对多建在任意一方都可以 如果建在作者表 字段顺序互换即可'''
books = models.ManyToManyField(
to='Author',
through='Book2Author', # 指定表
through_fields=('author','book') # 指定字段
)
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')