300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Django08-1:模型层(ORM)--聚合查询/分组查询/F与Q查询/开启事务/常用字段及参数/自定

Django08-1:模型层(ORM)--聚合查询/分组查询/F与Q查询/开启事务/常用字段及参数/自定

时间:2022-04-07 17:50:04

相关推荐

Django08-1:模型层(ORM)--聚合查询/分组查询/F与Q查询/开启事务/常用字段及参数/自定

聚合查询

单独使用时,用aggregate

1.只要是跟数据库相关的模块

基本都在django.db.models里面

如果没有应该在django.db里面

2.聚合查询通常配合分组使用

from django.db.models import Avg, Sum, Max, Min, Count# 1.所有书的平均价格res=models.Book.objects.aggregate('price')ret = models.Book.objects.all().aggregate(price_avg=Avg("price"), price_max=Max("price"), price_min=Min("price"))

分组查询

annotate

models后面点什么,就是什么分组

# 1.查询每一本书的作者个数ret = models.Book.objects.all().annotate(author_num=Count("author")).values('title','author_num')print(ret)#author_num 自定义字段,用来统计每本书个数。#等价ret = models.Book.objects.all().annotate(author_num=Count("author__pk")).values('title','author_num')print(ret)

只要结果是queryset对象,就可以继续.filter()和.values()

#2.统计每个出版社的最便宜书的价格res=models.Publish.objects.annote(min_price=Min('book__price')).values('name','min_price')#3. 统计不止一个作者的图书#a.先分组书籍,求每一步书籍的作者个数#b. 过滤不止一个作者的书籍res=models.Book.objects.annote(author_num=Count('authors')).filter(author_num__gt=1).value('title','author_num')

#4. 查询每个作者出的书的总价格res=models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')

扩展,其他分组方式

models.Book.values('price').annotate()

分组报错情况:去掉严格模式

F与Q查询

F功能:直接获取表中某个字段对应的数据

操作字符时,F不能直接做到字符拼接,

否则变成空白

# 1.查询卖出数大于库存书的书籍# F查询from django.db.models import Fres=models.Book.objects.filter(maichu__gt=F('kuncun'))# 2.将所有书的价格提升50models.Book.objects.update(price=F('price')+50)# 3.将所有书的名字后面加“爆款”两个字#***操作字符时,F不能直接做到字符拼接#***否则变成空白#需要导入两个模块from django.db.models.functions import Concatfrom django.db.models import Valuemodels.Book.objects.update(title=Concat(F('tittle'),Value('爆款')))

Q功能:能改变多个查询条件的关系,与或非

# Q 查询# 1.查询卖出数大于100 或者价格小于600的书籍res= models.Books.objects.filter(maichu__gt=100,price__lt=600)#错误,filter内是and关系from django.db.models import Qres= models.Books.objects.filter(Q(maichu__gt=100),Q(price__lt=600)) #还是and关系res= models.Books.objects.filter(Q(maichu__gt=100)|Q(price__lt=600)) #Q可以用 |res= models.Books.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600)) #前面取反# Q高阶用法 能够将查询条件左边变成字符串形式q=Q()q.connector='or' #**修改关系q.children.append('maichu__gt',180)q.children.append('price__lt',600)res= models.Books.objects.filter(q) #filter 也支持直接放q对象,默认还是and关系

开启事务

事务ACID

事务回滚

事务确认

from django.db import transactiontry:with transaction.atomic(): #开始事务操作# 先创建一个出版社new_publisher = models.Publisher.objects.create(name="火星出版社")# 创建一本书models.Book.objects.create(title="橘子物语",price=11.11,kucun=10,maichu=10,publisher_id=1000 # 指定一个不存在的出版社id)except Exception as e:print(str(e))

orm中常用字段及参数

AutoFieldint自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。CharField (sql:varchar)字符类型,必须提供max_length参数, max_length表示字符长度。#****所有字段都有verbose_name 字段注释*****IntegerField一个整数类型,范围在 -2147483648 to 2147483647。BigIntegerFieldDecimalField(Field)- 10进制小数- 参数:max_digits,小数总长度decimal_places,小数位长度EmailField(CharField): varchar(254)- 字符串类型,Django Admin以及ModelForm中提供验证机制DateField日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。DateTimeField日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。auto_now:每次操作数据的时候,该字段会自动将当前时间更新auto_now_add:创建数据的时候会自动将当前时间记录下来,之后只要不是人为修改,那么一直不变BooleanField(Field)- 布尔值类型数据库存0、1TextField(Field)- 文本类型没有字数限制FileField(Field) -字符- 字符串,路径保存在数据库,文件上传到指定目录- 参数:upload_to = ""上传文件的保存路径storage = None存储组件,默django.core.files.storage.FileSystemStorage例如:upload_to = "/data" 会自动将文件保存/data目录下,然后将文件路径保存到数据库 ###外键字段#django版本不同,级联可能需要手动设置

自定义字段

首先参考常用的字段

# 自定义char类型class MyCharField(models.Field):"""自定义的char类型的字段类"""def __init__(self, max_length, *args, **kwargs): # max_length指定字符串宽度self.max_length = max_lengthsuper(MyCharField, self).__init__(max_length=max_length, *args, **kwargs)def db_type(self, connection):"""限定生成数据库表的字段类型为char,长度为max_length指定的值"""return 'char(%s)' % self.max_length # 返回 'char(32)' 在数据库中就是char类型宽度32 # char类型字段的使用 class Class(models.Model):id = models.AutoField(primary_key=True)title = models.CharField(max_length=25)# 使用自定义的char类型的字段cname = MyCharField(max_length=25)

数据库查询优化

ORM语句的特点

惰性查询:只写orm语句,没有使用,orm不会查询数据库。

defer 和 only

res=models.Book.objects.all()print(res) # 要用数据库才查找数据库#获取书籍表中所有的书的名字res=models.Book.objects.values('title')##only#获取对象,只有title,没有其他字段。res=models.Book.objects.only('title')for i in res:print(i.title) #only 括号内的字段,不会走数据库print(i.price) #only 括号外的字段,重新走数据库 all()不需要走数据库#deferres=models.Book.objects.defer('title')for i in res:print(i.price) #defer与only 刚好相反。括号内走数据库,括号外不需要找数据库。

select_related 与prefetch_related

与跨表操作有关

res=models.Book.objects.all()for i in res:print(i.publish.name) #每循环一次就走一次数据库res=models.Book.objects.select_related('publish') #inner join#select_related内部直接将book与pulish连接起来,然后一次性将大表里的所有数据#全部封装给查询出来的对象# 这时候无论.book表数据还是publish数据都无需要走数据查询# select_related括号内只能放外键字段 一对多,一对一#多对多不行for i in res:print(i.publish.name)#连多表select_related('a__b__c')###prefetch_relatedres=models.Book.objects.prefetch_related('publish')# prefetch_related 实际是子查询# 子查询的结果分装到对象中# 用户感觉不出多一个命令for i in res:print(i.publish.name)#联表查询,遇到大表,效率就慢。

Django08-1:模型层(ORM)--聚合查询/分组查询/F与Q查询/开启事务/常用字段及参数/自定义字段/数据库查询优化

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。