第五章、Django之多表查询

一、聚合查询

关键字aggregate

from django.db.models import Max,Min,Count,Sum,Avg
统计所有书平均价格
res = models.Book.objects.all().aggregate(Avg('price'))
res1 = models.Book.objects.all().aggregate(Max('price'))
res2 = models.Book.objects.all().aggregate(Min('price'))
res3 = models.Book.objects.all().aggregate(Sum('price'))
res4 = models.Book.objects.all().aggregate(Count('title'))
res5 = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price'),Sum('price'),Count('title'))
print(res5)

二、分组查询

关键字:annotate

#1.统计每一本书的作者个数
res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num')
print(res) #2.统计出每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(price_min=Min('book__price')).values('price_min')
print(res)
# 3.统计不止一个作者的图书
"""
1.统计每本书对应的作者个数
2.基于上面的结果 筛选出作者个数大于1 的 """
# res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('author_num')
# print(res) # 4.查询各个作者出的书的总价格
# res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('sum_price')
# print(res)

三、F与Q查询

"""
F与Q查询
我们之前在查询数据库的时候条件都是我们自己手写的
但是现在出现了条件是从数据库里面获取的
"""
 # F
from django.db.models import F,Q
# 1.查询出卖出数大于库存数的书籍
# res = models.Book.objects.filter(maichu__gt=F('kucun'))
# print(res) # 2.将所有的书的价格 全部提高100块
# models.Book.objects.update(price=F('price') + 100) # 3.了解 尝试着将所有的书的名字后面都加上 爆款

# Q查询

    # 1.查询书籍名称是python入门或者价格是544.44的书
# res = models.Book.objects.filter(title='python入门',price=544.44)
# res = models.Book.objects.filter(Q(title='python入门'),Q(price=544.44)) # 逗号就是and
# res = models.Book.objects.filter(Q(title='python入门')|Q(kucun=666)) # 用来Q之后 就能够支持|表示或
# res = models.Book.objects.filter(~Q(title='python入门')|Q(kucun=666)) # esc下面那个键 波浪号 表示非
# print(res) # Q查询进阶用法 用Q产生对象 然后再使用
# q = Q()
# q.connector = 'or'
# q.children.append(('title__icontains','p'))
# # q.children.append(('kucun',666))
# res = models.Book.objects.filter(q)
# print(res)
"""
字符串的左边 跟你的变量名条件书写一模一样
"""

四、查询优化

only与defer

# res = models.Book.objects.all()
# res = models.Book.objects.values('title')
# res = models.Book.objects.only('title')
# for r in res:
# # print(r.title)
# print(r.price)
"""
only会将括号内的字段对应的值 直接封装到返回给你的对象中 点该字段 不需要再走数据库
一旦你点了不是括号内的字段 就会频繁的去走数据库查询
"""
# res = models.Book.objects.defer('title')  # defer和only互为反关系
# for r in res:
# print(r.title)
"""
defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中 点该其他字段 不需要再走数据库
一旦你点了括号内的字段 就会频繁的去走数据库查询
"""

连表操作和子查询


select_related 连表操作
# res = models.Book.objects.select_related('publish')
# res1 = models.Author.objects.select_related('author_detail')
# # res = models.Book.objects.all()
# for r in res1:
# print(r.author_detail)
# print(r.author_detail.phone)
# print(r.author_detail.addr)
"""
select_related 会自动帮你做连表操作 然后将连表之后的数据全部查询出来封装给对象 select_related括号内只能放外键字段
并且多对多字段不能放 如果括号内外键字段所关联的表中还有外键字段 还可以继续连表
select_related(外键字段__外键字段__外键字段...) """ ----------------------------------------------------------------------------------------------
# prefetch_related子查询
res = models.Book.objects.prefetch_related('publish')
# print(res)
for r in res:
print(r.publish.name) """
prefetch_related 看似连表操作 其实是类似于子查询
prefetch_related括号内只能放外键字段
并且多对多字段不能放 如果括号内外键字段所关联的表中还有外键字段 还可以继续连表
select_related(外键字段__外键字段__外键字段...) 总结
第一个 内部自动连表 消耗的资源就在连表上 但是走数据库的次数较少
第二个 内部不做连表 消耗的资源就在查询次数上 但是给用户的感觉跟连表操作一样

五、Django开启事务

from django.db import transaction
with transaction.atomic():
# 在该代码块中所写的orm语句 同属于一个事务
# 缩进出来之后自动结束 #-------------------------------------------------------------------------------
from django.db import transaction
from rest_framework.views import APIView class OrderAPIView(APIView):
def post(self,request):
....
with transation.atomic(): # 开启事务,当with语句执行完成以后,自动提交事务
pass # 数据库操作

六、自定义char字段

    class MyCharField(models.Field):
def db_type(self,connection):
return 'char(%s)'%self.max_length

七、ORM常用字段

AutoField

int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

IntegerField

一个整数类型,范围在 -2147483648 to 2147483647。

CharField

字符类型,必须提供max_length参数, max_length表示字符长度。

DateField

日期字段,日期格式  YYYY-MM-DD,相当于Python中的datetime.date()实例。

DateTimeField

日期时间字段,格式 YYYY-MM-DD HH:MM:ss[.uuuuuu],相当于Python中的datetime.datetime()实例

最新文章

  1. chrome防止自动填充密码
  2. EditText获取和失去焦点,软键盘的关闭,和软键盘的显示和隐藏的监听
  3. ubuntu14.04安装sipp3.2
  4. Vim 练级攻略
  5. Swagger PHP使用指南
  6. android 安装 出现Android Native Development Tools不能安装
  7. 【C语言】测试系统各数据类型大小代码
  8. C/C++中虚函数的调用
  9. iphone手机用wireshark抓包
  10. 【转】git命令
  11. Uva - 177 - Paper Folding
  12. redis删除所有key
  13. Linux之增加系统调用[内核编译]
  14. 对象缓冲池 ( cc.pool ) :
  15. 怎样从外网访问内网WampServer?
  16. D3_book 11.2 stack
  17. modelsim编译Xilinx器件库的另一种方法(节省时间)
  18. Salt-ssh批量自动安装被控端salt-mini
  19. ios开发之--[_NSInlineData objectForKeyedSubscript:]
  20. Django初级手册1-项目和应用的创建与简单的数据库操作

热门文章

  1. L1、L2正则化详解
  2. prometheus部署安装
  3. OpenGL学习(4)——纹理
  4. AWS物联网解决方案之:如何将设备安全地接入AWS IoT
  5. openat与open的区别及用法示例
  6. [LuoguP2167][SDOI2009]Bill的挑战_容斥原理/状压dp
  7. [bzoj3060][Poi2012]Tour de Byteotia_并查集
  8. kafka 名词解释及原理解析过程(三)
  9. 正式发布! .NET开发控件集ComponentOne 新版本加入Blazor UI
  10. vue中使用第三方插件animate.css实现动画效果