#====================================双下划线的跨表查询===============
# 前提 此时 related_name=bookList
属性查询:
# 查询linux这本书的出版社的地址? # linux_obj=models.Book.objects.filter(title="linux").first()
# print(linux_obj.publish.name)
#
# # 查询老男孩出版社出版过的所有书籍的名字与价格
#
# pubObj=models.Publish.objects.filter(name="老男孩出版社").first()
# print(pubObj.bookList.all().values("title","price")) #此时 related_name=bookList 双下划线查询 : .filter(过滤的条件) .values(要显示的值)   注意:如果在没有定义 related_name 时,反向查询时 直接用表名,不需要加 _set # 查询linux这本书的出版社的地址? --正向查询
#ret=models.Book.objects.filter(title="linux").values("publish__addr")
# print(ret) #或                  --反向查询
# ret=models.Publish.objects.filter(bookList__title="linux").values("addr")
# print(ret) # 查询老男孩出版社出版过的所有书籍的名字与价格 # ret1=models.Publish.objects.filter(name="老男孩出版社").values("bookList__title","bookList__price")
# print(ret1)
#
# ret2=models.Book.objects.filter(publish__name="老男孩出版社").values("title","price")
# print(ret2) #查询egon出过的所有书籍的名字(多对多) ret=models.Author.objects.filter(name="egon").values("bookList__title")
print(ret) ret2=models.Book.objects.filter(authorlist__name="egon").values("title")
print(ret2) # egon出版过的所有书籍名称以及出版社名称 ret=models.Book.objects.filter(authorlist__name='egon').values('title','Publish__name') # 手机号以151开头的作者出版过的所有书籍名称以及出版社名称 # 方法1:
# ad=models.AuthorDetail.objects.filter(tel__startswith="151").first()
# print(ad.author.bookList.all().values("title","publish__name")) # 方法2
models.Book.objects.filter(authorlist__authordetail__tel__startswith="").values("title","publish__name")
#================================================================聚合函数
  注明:下方的所有all() 都可以省略 。 不加values / values_list 得到的就是包含对象的QuerySet,加上了就是包含字典/元组的QuerySet from django.db.models import Avg,Sum,Count,Max,Min # 聚合函数:aggregate
# 查询所有图书的价格和 ret=models.Book.objects.all().aggregate(priceSum=Sum("price"))
print(ret) # {'priceSum': Decimal('166.00')} ret=models.Book.objects.all().aggregate(priceAvg=Avg("price"),priceSum=Sum("price"))
   #单独使用aggregate 函数聚合时,返回的是 字典 # 分组函数 annotate函数 # 查询每一本书的作者个数 book_list=models.Book.objects.all().annotate(c=Count("authorlist__name")) #此时的book_list 是一个QuerySet
for book_obj in book_list:
print(book_obj.c) #按照原来得所有字段进行分组-相当于与原表一样-,默认分成一组, 并且分组后会在新表中新增一个 c 的字段   print(book_list)
  #结果:------------------------- <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>, <Book: Book object>, <Boo
  k: Book object>, <Book: Book object>]> # 查询每一个出版社出版过的最便宜的书籍
ret=models.Book.objects.all().values('publish__id').annotate(Min("price")) #values内的字段就是分组字段
print(ret)
 
  #结果:------------------------- <QuerySet [{'publish__id': 1, 'price__min': Decimal('120.00')}, {'publish__id': 2, 'price__min': Decimal('520.00')}, {'p
  ublish__id': 3, 'price__min': Decimal('222.00')}]>   # 查询每一个出版社出版过的书籍个数
  ret=models.Book.objects.all().values('publish__id').annotate(c=Count('name'))    #values内的字段就是分组字段
  print('-------------------------',ret)
  #结果:------------------------- <QuerySet [{'publish__id': 1, 'c': 5}, {'publish__id': 2, 'c': 1}, {'publish__id': 3, 'c': 1}]>
     分组后得到的是一个QuerySet集合,里面得到的是字典形式的数据,并且只有分组依据和聚合函数的两个字段

F  与 Q  查询

F查询

在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。 # 查询评论数大于收藏数的书籍
 
   from django.db.models import F    Book.objects.filter(commnetNum__gt=F('keepNum')) Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。 # 查询评论数大于收藏数2倍的书籍
    Book.objects.filter(commnetNum__gt=F('keepNum')*2) 修改操作也可以使用F函数,比如将每一本书的价格提高30元: Book.objects.all().update(price=F("price")+30)  
Q查询 filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。 from django.db.models import Q Q(title__startswith='Py') Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。 bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon")) 等同于下面的SQL WHERE 子句: WHERE name ="yuan" OR name ="egon" 你可以组合& 和|  操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询: bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title") 查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如: bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),title__icontains="python")

python-day71--django多表双下划线查询及分组聚合及F/Q查询的更多相关文章

  1. django 神奇的双下划线,通过外键的三种查询方式

    一,用于跨表操作 只要是object后面字符串都是用双下划线__.其它地方用点. 如:的values中的group_code__name.group_code是一个外键 def list(reques ...

  2. django orm 基于双下划线的跨表查询

    一..基于双下划线的跨表查询(join实现) key:正向查询按字段,反向查询按表明小写 1.一对多跨表查询 查询在跨表中可以有两种方式,正向查询就是关键字段在你要搜索的表,没有关键字段就是反向查询 ...

  3. django之ORM专项训练之图书信息系统 了不起的双下方法实战 和 分组 聚合 Q, F查询,有約束和無約束

    图书信息系统 双下方法的使用情况:要查确定的某一个对象他的属性值时, 首先获得具体对象的方法是  get()   first()   last()   获得具体对象之后,在找他的外键的属性    ge ...

  4. Python中的魔术(双下划线'__xxx__')方法详解

    介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,中文称『魔术方法』,例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中 ...

  5. 模型层字段-多表查询-神奇的双下划线查询-F,Q查询

    Django ORM中常用的字段和参数 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. In ...

  6. Python中单下划线与双下划线用法总结

    看mentor的脚本时,遇到self._item.callspec.getparam('')语句,理解起来比较困难,找到一篇文章,记录的比较详细,特别记录一下,以备复习. 附链接地址:http://w ...

  7. $Django 多表操作(增删改查,基于双下划线,对象的查询) 在Python脚本中调用Django环境

    在Python脚本中调用Django环境. import osif __name__ == '__main__': os.environ.setdefault("DJANGO_SETTING ...

  8. django models的点查询/跨表查询/双下划线查询

    django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...

  9. Django 数据库查询集合(双下划线连表操作)

    Django是一款优秀的web框架,有着自己的ORM数据库模型.在项目中一直使用django数据库,写一篇文章专门记录一下数据库操作.略写django工程创建过程,详写查询过程.可以和sqlalche ...

随机推荐

  1. UI之ECharts

    官网 效果图展示: 特性 ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Fir ...

  2. Kubernetes之Controllers二

      Deployments A Deployment controller provides declarative updates for Pods and ReplicaSets. You des ...

  3. linux golang

    wget -c http://www.golangtc.com/static/go/go1.3.linux-386.tar.gz #下载32位Linux的够源码包 tar -zxvf go1.1.li ...

  4. JavaScript重点知识(一)

    一.总括 基础知识: 1.变量 2.原型和原型链 3.作用域和闭包 4.异步和单线程 JS的API: 1.BOM,DOM操作 2.事件绑定 3.Ajax 4.JSOP 5.存储 二.基础知识 2.1知 ...

  5. hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥

    Senior PanⅡ Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Pr ...

  6. 封装sqlhelper【一】

    控件信息展示: //定义调用数据库类文件 namespace SqlHelper { public class TblClass { public int classId { get; set; } ...

  7. NativeWindow_01_CreateWindow(Ex)_VC6

    1. #include <windows.h> LRESULT CALLBACK ProcWindow(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA ...

  8. 力扣(LeetCode) 9.回文数

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向 ...

  9. cordova + Vue 开发 APP 上手指南

    什么是 cordova cordova 是由 Apache 基金会支持的,使用 HTML5 + CSS3 + JS 来构建多平台 APP 程序的开发框架.其支持调用手机系统(Android.IOS.W ...

  10. CSS sprite使用

    CSS Sprites叫css精灵或者雪碧图,是一种网页图片应用处理方式. CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”, ...