day56
聚合函数
首先要导入聚合函数
from django.db.models import Max,Min,Sun,Avg,Count
筛选出价格最高的书籍
res=models.Book.objects.aggregate(min_price=Max('price'))
print(res)
{'min_price': Decimal('600.00')}
求书籍的总价格
res=models.Book.objects.aggregate(sum_price=Sum('price'))
print(res)
{'sum_price': Decimal('1700.00')}
求书籍平均价格
res=models.Book.objects.aggregate(avg_price=Avg('price'))
print(res)
{'avg_price': 425.0}
也可以一起使用
res=models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Count('price'),Avg('price'))
print(res)
{'price__max': Decimal('600.00'), 'price__min': Decimal('200.00'), 'price__sum': Decimal('1700.00'), 'price__count': 4, 'price__avg': 425.0}
分组查询
统计每一本书的作者个数 书名 和对应的作者人数
res=models.Book.objects.annotate(num=Count('authors__id')).values('title','num')
print(res)
<QuerySet [{'title': '西游记', 'num': 2}, {'title': '红楼梦', 'num': 0}, {'title': '水浒传', 'num': 1}, {'title': '三国演义', 'num': 1}]>
统计出每个出版社卖的最便宜的书的价格 出版社的名字 价格
res=models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
print(res)
<QuerySet [{'name': '东方出版社', 'min_price': Decimal('400.00')}, {'name': '北方出版社', 'min_price': Decimal('200.00')}]>
按照其他字段分组
res = models.Publish.objects.values('想要分组的字段名').annotate(min_price=Min('book__price')).values('name','min_price')# print(res)
统计不止一个作者的图书
res=models.Book.objects.annotate(num=Count('authors')).filter(num__gt=1).values('title','num')
print(res)
<QuerySet [{'title': '西游记', 'num': 2}]>
查询各个作者出的书的总价格 作者名字 总价格
res=models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
print(res)
<QuerySet [{'name': '王俊义', 'sum_price': Decimal('400.00')}, {'name': '主帅雷', 'sum_price': Decimal('600.00')}, {'name': '季军', 'sum_price': Decimal('500.00')}]>
F与Q查询
from django.db.models import F,Q
查询库存数大于卖出数的书籍
res = models.Book.objects.filter(kun_cun__gt = F('mai_cun')).values('title') 后面的条件是来自于数据库的其他字段值
print(res)
将所有书的价格上涨100块
models.Book.objects.all().update(price=F('price') + 100)
将所有书的名称后面全部加上 "爆款" 后缀 了解知识点 操作字符串数据需要借助于Concat方法
from django.db.models.functions import Concat
from django.db.models import Value
ret3 = models.Book.objects.update(title=Concat(F('title'), Value('新款')))
接下来是q查询
查询一下书籍名称是三国演义 或者 库存数是500的书籍
res = models.Book.objects.filter(Q(title='三国演义'),Q(kun_cun=500)) # Q包裹之后逗号还是and关系
res = models.Book.objects.filter(Q(title='三国演义') | Q(kun_cun=500)) # |就是or的关系
res = models.Book.objects.filter(~Q(title='三国演义') | Q(kun_cun=500)) # ~就是not关系
print(res)
Q对象高级用法
q = Q()
q.connector = 'or' # 默认是and 可以改成or(**********)
q.children.append(('title','三国演义'))
q.children.append(('kun_cun__gt',500))
res = models.Book.objects.filter(~q) # 取反
print(res)
orm字段及参数
CharField varchar
IntegerField int
BigIntegerField bigint
EmailField varchar(254)
DateField
DateTimeField
auto_now:每次修改数据的时候 都会自动将当前修改时间更新上去 实时更新
auto_now_add:在创建数据的时候 会将当前时间自动记录 之后不会自动修改 除非你人为修改
AutoField auto_increment
BooleanField 布尔值
该字段在存储的时候 你只需要传布尔值True或False
它会自动存成1/0
TextField 专门用来存大段文本
FileField 专门用来文件路径 '/etc/data/a.txt'
upload_to = '/etc/data'
给该字段传值的时候 直接传文件对象
会自动将文件对象保存到upload_to后面指定的文件路径中
然后将路径保存到数据库
DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
自定义char字段
class MyCharField(models.Field):
def __init__(self ,max_length,*args,**kwargs):
self.max_length=max_length
super().__init__(max_length=max_length,*args,**kwargs)
def db_type(self,connection):
return 'char(%s)'%self.max_length
orm中的事务操作
什么是事务
四大特性
ACID
原子性 一致性 隔离性 持久性
记一个转账的例子
为了保证数据安全 事务操作
rollback() 回滚就是回到上一个状态
django如何开启事务
from django.db import transaction
with transaction.atomic():
# 在缩进的代码中书写数据库操作
# 该缩进内的所有代码 都是一个事务
pass