基于双下划线的双表查询

分组与聚合函数

基于双下划线的双表查询

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查询进阶的更多相关文章

  1. Django之ORM查询复习与cookie

    ORM查询总结: models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwa ...

  2. Django之ORM查询

    ORM 映射关系: 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象图书管理系统的增删改查:代码如下:views ...

  3. Django 的 orm 查询

    一.模型关系表 1. 一对一 Author-AuthorDetail 关联字段可以在任意表下,但必须唯一约束.(unique约束) ad_id(unique约束) ad = models.oneToO ...

  4. [django]django的orm查询

    实体 实体 出版社 category 作者 tag 书 文章 先学习一下基础的增删查改 django orm增删改查: https://www.cnblogs.com/iiiiiher/article ...

  5. django优化--ORM查询

    ORM提供了两个方法用来优化查询效率 1. select_related 有两张表:表结构如下: class Scheme(models.Model): """ 套餐类 ...

  6. Django之ORM查询操作详解

    浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Python脚本中调用Django环境 其他操 ...

  7. 【python】-- Django ORM(进阶)

    Django ORM(进阶) 上一篇博文简述了Django ORM的单表操作,在本篇博文中主要简述Django ORM的连表操作. 一.一对多:models.ForeignKey() 应用场景:当一张 ...

  8. 第五章、Django之多表查询进阶与事务

    目录 第五章.Django之多表查询 一.聚合查询 二.分组查询 三.F与Q查询 四.查询优化 五.Django开启事务 六.自定义char字段 七.ORM常用字段 第五章.Django之多表查询 一 ...

  9. Django 源码小剖: Django ORM 查询管理器

    ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...

随机推荐

  1. PowerDesigner版本控制器设置权限

    PowerDesigner版本控制权限之前一直在Groups里面设置,一直没有效果,原因终于找出来了,PowerDesigner是要对每个库单独赋权限的,步骤如下: 连接上版本控制,在左侧菜单 Obj ...

  2. Extjs4---Cannot read property 'addCls' of null 或者 el is null 关于tab关闭后再打开不显示或者报错

    做后台管理系统时遇到的问题,关于tab关闭后再打开不显示,或者报错 我在新的tabpanel中加入了一个grid,当我关闭再次打开就会报错Cannot read property 'addCls' o ...

  3. .net网站上传图片换电脑不显示

    当不用网站的IP地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可.

  4. c#实战开发:以太坊Geth 常用命令 (四)

    首先运行客户端  当前命令分为 eth,web3 ,personal ,net 输入 >eth 可以看到该命令下的所有方法 > eth 1.创建用户 personal.newAccount ...

  5. Java基础——Oracle(五)

    一.Oracle  中的分页 1) select * from emp; 2)select * ,rownum from emp; //这样写不行 3)select ename,job,sal,row ...

  6. Java使用foreach语句对数组成员遍历输出

    /** * 本程序使用foreach语句对数组成员进行遍历输出 * @author Lei * @version 2018-7-23 */ public class ForeachDemo { pub ...

  7. Why in the code “456”+1, output is “56”

    Question: #include <iostream> int main() { std::cout << "25"+1; return 0; } I ...

  8. JavaScript--fullPage.js插件

    GitHub:https://github.com/alvarotrigo/fullPage.js FullPage.js是一个基于JQuery的插件,可以很方便的制作出全屏网站; 一 特点: 1.支 ...

  9. VUE基于ElementUI搭建的简易单页后台

    一.项目链接 GitHub 地址: https://github.com/imxiaoer/ElementUIAdmin 项目演示地址:https://imxiaoer.github.io/Eleme ...

  10. 记录修改安卓5.0系统浏览器UI遇到的部分问题

    碎碎念 今年七月份本科毕业后入职一家会议平板公司,经过一个一个多月的咸鱼培训轮岗生活,接手了几个小任务,本次记录一下其中一个任务:修改安卓5.0系统浏览器UI.刚接到任务的时候,本以为是很简单的一个任 ...