Django之ORM查询进阶
基于双下划线的双表查询
分组与聚合函数
基于双下划线的双表查询
Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的 model 为止。
# 练习1: 查询人民出版社出版过的所有书籍的名字与价格(一对多)
# 正向查询 按字段:publish
queryResult=Book.objects
.filter(publish__name="人民出版社")
.values_list("title","price")
# 反向查询 按表名:book
queryResult=Publish.objects
.filter(name="人民出版社")
.values_list("book__title","book__price")
# 练习2: 查询egon出过的所有书籍的名字(多对多)
# 正向查询 按字段:authors:
queryResult=Book.objects
.filter(authors__name="yuan")
.values_list("title")
# 反向查询 按表名:book
queryResult=Author.objects
.filter(name="yuan")
.values_list("book__title","book__price")
# 练习3: 查询人民出版社出版过的所有书籍的名字以及作者的姓名
# 正向查询
queryResult=Book.objects
.filter(publish__name="人民出版社")
.values_list("title","authors__name")
# 反向查询
queryResult=Publish.objects
.filter(name="人民出版社")
.values_list("book__title","book__authors__age","book__authors__name")
# 练习4: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称
queryResult=Book.objects
.filter(authors__authorDetail__telephone__regex="")
.values_list("title","publish__name")
代码
#手机号以456开头的作者出版过的所有书籍的名字以及出版社的名字
#方法1
authorobj=models.AuthorDetail.objects.filter(telph__startswith="456").first()
# print(authorobj.authordetail.book_set.all().values("title","publish__name"))
#方法2
# print(models.Book.objects.filter(authorlist__authordetail__telph__startswith="456").values("title","publish__name"))#都是通过自己里面的字段跳转到别的字段
注意:
反向查询时,如果定义了related_name ,则用related_name替换表名,例如: publish = ForeignKey(Blog, related_name='bookList'):
# 练习1: 查询人民出版社出版过的所有书籍的名字与价格(一对多)
# 反向查询 不再按表名:book,而是related_name:bookList
queryResult=Publish.objects
.filter(name="人民出版社")
.values_list("bookList__title","bookList__price")
代码
注意: 双下划线的跨表查询 不用__set了
#双下划线的跨表查询
# linux这本书的出版社的地址
# ret=models.Book.objects.filter(title="linux").values("publish__addr")
# print(ret)
# ret=models.Publish.objects.filter(book__title="linux").values("addr")
# print(ret)
#查询机械出版社出版过的所有书籍的名字与价格
# ret=models.Publish.objects.filter(name="机械出版社").values("book__title","book__price")
# print(ret)
# models.Book.objects.filter(publish__name="机械出版社").values("title","price")
# print(ret)
#查询frank出过所有书籍的名字
# ret=models.Author.objects.filter(name="frank").values("book__title","book__price")
# print(ret)
# ret1=models.Book.objects.filter(authorlist__name="frank").values("title","price")
# print(ret1)
#手机号以456开头的作者出版过的所有书籍的名字以及出版社的名字
#方法1
authorobj=models.AuthorDetail.objects.filter(telph__startswith="").first()
# print(authorobj.authordetail.book_set.all().values("title","publish__name"))
#方法2
# print(models.Book.objects.filter(authorlist__authordetail__telph__startswith="456").values("title","publish__name"))#都是通过自己里面的字段跳转到别的字段 #聚合函数
from django.db.models import Avg,Sum,Count,Max,Min
# ret =models.Book.objects.all().aggregate(priceSum=Sum("price"))#结果是字典可以替换名字
# ret = models.Book.objects.all().aggregate(priceAVG=Avg("price"),priceSum=Sum("price"))
# print(ret)
# 分组函数 annote函数
#查询每一本书的作者个数
# ret= models.Book.objects.all().annotate(c=Count("authorlist__name"))
# print(ret)#Queryset对象 #每一个出版社出版过的最便宜的书:
cc=models.Publish.objects.all().annotate(s=Min("book__price"))#如果是跨表查询就用表明__加id
for i in cc:
print(i.s)
聚合查询与分组查询
聚合:aggregate(*args, **kwargs)
:aggregate(*args, **kwargs)
1
2
3
4
# 计算所有图书的平均价格
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。
>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}
如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}#Decimal数据格式
分组:annotate()
为QuerySet中每一个对象都生成一个独立的汇总值。
(1) 练习:统计每一本书的作者个数
#查询每一本书的作者个数
# ret= models.Book.objects.all().annotate(c=Count("authorlist__name"))
# print(ret)#Queryset对象
(2)每一个出版社出版过的最便宜的书:
cc=models.Publish.objects.all().annotate(s=Min("book__price"))#如果是跨表查询就用表明__加id
for i in cc:
print(i.s)
annotate的返回值是querySet,如果不想遍历对象,可以用上valuelist:
queryResult= Publish.objects
.annotate(MinPrice=Min("book__price"))
.values_list("name","MinPrice")
print(queryResult)
方式2:
queryResult=Book.objects.values("publish__name").annotate(MinPrice=Min('price'))
注意:values内的字段即group by的字段
(3) 统计每一本以py开头的书籍的作者个数:
queryResult=Book.objects
.filter(title__startswith="Py")
.annotate(num_authors=Count('authors'))
(4) 统计不止一个作者的图书:
queryResult=Book.objects
.annotate(num_authors=Count('authors'))
.filter(num_authors__gt=1)
(5) 根据一本图书作者数量的多少对查询集 QuerySet进行排序:
Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')
(6) 查询各个作者出的书的总价格:
# 按author表的所有字段 group by
queryResult=Author.objects
.annotate(SumPrice=Sum("book__price"))#跳转到另一个表里
.values_list("name","SumPrice")
print(queryResult) #按authors__name group by
queryResult2=Book.objects.values("authors__name")
.annotate(SumPrice=Sum("price"))
.values_list("authors__name","SumPrice")
print(queryResult2)
注意:很多代码没有加models
Django之ORM查询进阶的更多相关文章
- Django之ORM查询复习与cookie
ORM查询总结: models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwa ...
- Django之ORM查询
ORM 映射关系: 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象图书管理系统的增删改查:代码如下:views ...
- Django 的 orm 查询
一.模型关系表 1. 一对一 Author-AuthorDetail 关联字段可以在任意表下,但必须唯一约束.(unique约束) ad_id(unique约束) ad = models.oneToO ...
- [django]django的orm查询
实体 实体 出版社 category 作者 tag 书 文章 先学习一下基础的增删查改 django orm增删改查: https://www.cnblogs.com/iiiiiher/article ...
- django优化--ORM查询
ORM提供了两个方法用来优化查询效率 1. select_related 有两张表:表结构如下: class Scheme(models.Model): """ 套餐类 ...
- Django之ORM查询操作详解
浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Python脚本中调用Django环境 其他操 ...
- 【python】-- Django ORM(进阶)
Django ORM(进阶) 上一篇博文简述了Django ORM的单表操作,在本篇博文中主要简述Django ORM的连表操作. 一.一对多:models.ForeignKey() 应用场景:当一张 ...
- 第五章、Django之多表查询进阶与事务
目录 第五章.Django之多表查询 一.聚合查询 二.分组查询 三.F与Q查询 四.查询优化 五.Django开启事务 六.自定义char字段 七.ORM常用字段 第五章.Django之多表查询 一 ...
- Django 源码小剖: Django ORM 查询管理器
ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...
随机推荐
- Python机器学习笔记:深入学习Keras中Sequential模型及方法
Sequential 序贯模型 序贯模型是函数式模型的简略版,为最简单的线性.从头到尾的结构顺序,不分叉,是多个网络层的线性堆叠. Keras实现了很多层,包括core核心层,Convolution卷 ...
- 【JAVA WEB教程】jsp环境搭建+部署网站(eclipse+tomcat)【详细+图文】
下载tomcat7.X 下载地址为:http://tomcat.apache.org/download-70.cgi 下载完成之后就开始安装 Next I Agree 选中所有的复选框 ...
- 一个简单有趣的Python音乐播放器
(赠新手,老鸟绕行0.0) Python版本:3.5.2 源码如下: __Author__ = "Lance#" # -*- coding = utf-8 -*- #导入相应模块 ...
- 深入浅出 JVM GC(1)
# 前言 初级 Java 程序员步入中级程序员的有一个无法绕过的阶段------GC(Garbage Collection).作为 Java 程序员,说实话,很幸福,不用像 C 程序员那样,时刻关心着 ...
- IOS 获取的时间显示为NAN 解决方法
var regTime= item.BeginDate.replace(/\-/g, "/"); ------ item.BeginDate 我的日期年月日的 (/\-/g, ...
- makefile中":=","=","?=","+="
= 无关位置的等于,值永远等于最后的值 比如: x =a y =$(x) x =b 那么y的值永远等于最后的值,等于 b ,而不是a := 有关位置的等于,值取决于当时位置的值 比如: ...
- Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解
目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...
- 【Java基础】4、java中的内部类
内部类的分类:常规内部类.静态内部类.私有内部类.局部内部类.匿名内部类. 实例1:常规内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...
- Maven+Mybatis一些简单例子
一.创建maven工程 把依赖的包写在pom.xml中.保存后,工程会有错,需要在工程上右键选择“Maven-->Update Project” pom.xml内容为 <project x ...
- cordova启动页面和图标的设置
一.config.xml配置 在cordova5.0版本以后,需要安装cordova-plugin-splashscreen插件以后才能修改和设置App的启动页面. 安装splashscreen插件: ...