聚合函数
首先要导入聚合函数
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