基于对象的跨表查询(sql里的子查询)(重点)

一对多查询:

Book(有外键)--------------->Publish     属于正向查询  按book表里的字段book.publish

Book(含外键)<---------------Publish    是反向查询   按表名小写_set.all()

正向查询      例如:查python这本书的出版社的名字和邮箱

book=Book.objects.filter(title="python").first()   #拿到对象,  对象.属性才可以获取值

print(book.publish.name)

print(book.publish.email)

反向查询   例如:查苹果出版社 出版的所有书籍的名字

pub_obj=Publish.objects.get(name="苹果出版社")

print(pub_obj.book_set.all())  #  print(pub_obj.book_set) 出版社找书, 因为出版过很多书,所以用 _set,   .all()是找出所有的书

多对多查询:

Book(有外键)--------------->Author     正向查询  按book表里的字段book.authors.all() 得到的是一个集合

Book(含外键)<---------------Publish    反向查询   按表名小写_set.all()

正向查询   例如找python作者的年龄

book=Book.objects.filter(title="python").first()    #拿到python这本书

ret = book.authors.all() # 拿到与这本书关联的所有作者queryset

ret2 = book.authors.all().value("age")

print(ret2)

反向查询    例如找alex出版过的书

alex=Author.objects.filter("name"="Alex").first()  #获取到alex对象  filter得到的是queryset   .first()得到的是对象

print(alex.book_set.all())

一对一查询

Author--------------->AuthorDetail     正向查询  按字段   alex.ad(Author表里的字段)

Author<---------------AuthorDetail     反向查询   按表名  ad.author(表名)

正向查询   例如:查询alex的手机号

alex=Author.objects.filter("name"="alex").first()

print(alex.ad.tel)

反向查询   例如:查手机号是110的用户名

ad=AuthorDetail.objects.filter(tel=110).first()

print(ad.author.name)

-------------------------------------------------------------------------------------------------

双下划线的跨表查询(基于sql中的join实现 ) (重点)

规则:正向查询按字段    反向查询按表名的小写    

不管以哪张表为基表,   写在最前面的过滤条件是不变的, 变的是过滤条件的书写方式, 就是按照上面的规则拼写

一对多

例1: 查python的出版社的名字和邮箱

以Book为基表   从Book 往Publish方向找   是正向查询

ret=Book.objects.filter(title="python").values("publish__name") #在values这开始跨表 告诉ORM的book表拼publish表

print(ret)

以Publish为基表  查出版python的出版社名字

ret=Publish.objects.filter(book__title="python").values("name")

#book__title="python"      title不在基表Publish中 所以先拼表book(title字段在book中)  再反向拼表按表名小写book__title

#values("name")      name是基表Publish自己的字段可以直接使用

例2: 查苹果出版社出版的所有的书的名字

以Book为基表 是正向查询

ret=Book.objects.filter(pubish__name="苹果出版社").values("title")

print(ret)

#苹果出版社不在基表Book里面,所以要先到Publish中把name="苹果出版社"的过滤出来

#title是Book基表自己的字段

以Publish为基表  反向查询

ret=Publish.objects.filter(name="苹果出版社").values("book__title"")

print(ret)

#name="苹果出版社"     name在基表Pubish里面,所以直接使用name字段

#title 不在基表Publish里面,   所以要先找到Book表 (通过表名小写的方式), 再__title

多对多

例1: 查python这本书作者的名字

以Book为基表      正查按字段

ret=Book.objects.filter(title="python").values("author__age")

print(ret)

#author      Book拼关联的author表   把三张表拼在一起

#title在基表Book里面

以Author为基表

ret=Author.objects.filter(book__title="python").values("age")

print(ret)

例2:  查alex出版过的书

以Book表为基表

ret=Book.objects.filter(authors__name="alex").values("title")

print(ret)  # [{ "title"=python }]

以Author表为基表

ret=Author.objects.filter(name="alex").values("book__title")

print(ret)  # [{ "book__title"=python }]        对比一下两种方式的查询结果

一对一

例1:  查alex的tel

以Author为基表   正向查询条件按字段

ret=Author.objects.filter(name="alex").values("ad__tel")

print(ret)

以AuthorDetail为基表

ret=AuthorDetail.objects.filter(authors__name="Alex").values("tel")

print(ret)

例2:手机号为110的作者的名字

以AuthorDetail为基表

ret=AuthorDetail.objects.filter(tel="110").values("author__name")

print(ret)

# tel在基表里面,所以直接查询.

# name不在基表里面,所以要加表名小写author__name

以Author为基表

ret=Author.objects.filter("ad__tel=110").values("name")

print(ret)

--------------------------------------------------------------------------------------------

连续跨表查询

例1:   人民出版社出版过所有书的名称以及作者的名字 (会用到Publish   Book   Author三张表)

以Publish为基表

ret=Publish.objects.filter(name="人民出版社").values("book__title","book__authors__name")

print(ret)

#name在基表的字段里, title和name需要用所在的表名小写连接起来再查询

#站在基表的角度跨表

以Book为基表

ret=Book.objects.filter(publish__name="人民出版社").values("title","author__name")

print(ret)

例2:  以手机号110开头的作者出版过的所有的 书的名称以及出版社名称(会用AD  Author  Book  Publish四张表 )

以Author为基表

ret=Author.objects.filter(ad__tel__startswith=110).values("book__title","book__publish__name")

print(ret)

#没有在基表里的查询字段都需要用加引号

------------------------------------------------------------------------------------------

聚合  分组查询

from django.db.models import Avg, Sum, Max, Min, Count

聚合

例1:  查询所有书籍的平均价

ret=Book.objects.all().aggregate(priceAvg=Avg("price"))

print(ret)   #{"priceAvg":123}

例2:  查有多少本书

ret=Book.objects.all().aggreagte(c=Count("nid"))

print(ret)   #{"c":4}

分组               以哪个字段分组 就把哪个字段放在values()里

单表分组查询

例1:  查询Book表中每个出版社的id以及对应出版书的个数

ret=Book.objects.values("title").annotate()

#按照title分组的group by          values里面是分组的字段

例2:  求每个部门的平均工资

ret=Emp.objects.values("dep").annotate(avg_salary=Avg("salary"))

# 按部门分组  求平均工资

例3:  求每个出版社  出版的书的个数

ret=Book.objects.values("pubish__id").annotate(c=Count(1))

#publish__id是Book表里的字段

print(ret)

#[{"publish_id":1, "c":2},  {"publish_id":2, "c":1},  {"publish_id":3, "c":1}]

跨表分组查询       以哪个字段分组 就把哪个字段放在values()里

例1:  查询每个出版社名称以及出版过的书的平均价格   查询什么 就以什么为基表简单点

ret=Publish.objects.values("nid").annotate(avg_price=Avg("book__price"))

# book__price拼表       按Publish表的nid分组

例2:  查询每一个作者的名字以及出版过的书的最高价    查询什么 就以什么为基表简单点

ret=Author.objects.values("name").annotate(maxPrice=Max("book__price"))

# book__price去Book表找price

例3: 查询每一个书名称以及对应的作者的个数   (Book  Author表)

ret=Book.objects.values("title").annotate(Count("authors"))     ?????????

例4:

ret=Publish.objects.all().annotate(avg_price=Avg("book_price")).values("name","email","avg_price")

#前面的查询结果  后面可以用????????????

例5:  查询作者数不止一个的书名以及作者的个数  (重点看看)

ret=Book.objects.annotate(c=Count("authors").filter(c__gt=1).values("title","c"))

# 添加到了Book对象的属性中了

-------------------------------------------------------------------------

F和Q查询:

F函数查询

例1:  查询评论数大于100的书名       以哪个字段分组 就把哪个字段放在values()里

ret=Book.objects.filter(comment_count__gt=100).values("title")

例2:  评论数大于点赞数

from django.db.models. import F,Q  (导入F Q函数)

ret=Book.objects.filter(comment_count__gt=F("poll_count"))

例3:  评论数大于2倍点赞数

ret=Book.objects.filter(comment_count__gt=F("poll_count")*2)

例4:  每本书的价格都在原价上加100

ret=Book.objects.all().update(price=100 + F("price"))

Q函数

例1:   查询价格大于300或者评论数大于3000的书籍

ret=Book.objects.filter(Q(price__gt=300 | Q(comment_count__gt=3000)))

ORM的查询的更多相关文章

  1. Django的ORM常用查询操作总结(Django编程-3)

    Django的ORM常用查询操作总结(Django编程-3) 示例:一个Student model: class Student(models.Model): name=models.CharFiel ...

  2. tornado 07 数据库—ORM—SQLAlchemy—查询

    tornado 07 数据库—ORM—SQLAlchemy—查询 引言 #上节课使用query从数据库查询到了结果,但是query返回的对象是直接可用的吗 #在query.py内输入一下内容 from ...

  3. Django之ORM优化查询的方式

    ORM优化查询的方式 一.假设有三张表 Room id 1 2 .. 1000 User: id 1 .. 10000 Booking: user_id room_id time_id date 1 ...

  4. Django orm进阶查询(聚合、分组、F查询、Q查询)、常见字段、查询优化及事务操作

    Django orm进阶查询(聚合.分组.F查询.Q查询).常见字段.查询优化及事务操作 聚合查询 记住用到关键字aggregate然后还有几个常用的聚合函数就好了 from django.db.mo ...

  5. Net/NetCore/.NET5 ORM 六大查询体系 - SqlSugar 高级篇

    框架介绍 SqlSugar ORM是一款老牌国产ORM框架,生命力也比较顽强,从早期ORM不成熟阶段,一直存活到现在,我为什么要一直坚持,那是因为还有很多用户在使用,本来我能够较早推出新开源框架 ,可 ...

  6. Moon.Orm 常见查询实例

    一.Moon.Orm框架总述 (您还用hibernate?实体框架?) 1.框架名:Moon 意思是月亮,而非Mono.因为很喜欢明月,所以以此为名.它是一个.NET下的Orm框架. 2.发展历史:历 ...

  7. 我的ORM之一 -- 查询

    我的ORM索引 概述 http://code.taobao.org/svn/MyOql/ 这是我自己写的开源ORM教程,我想先从场景示例中切入介绍,先有一个感性的认识,以小见大,触类旁通,有了这个认识 ...

  8. beego中orm关联查询使用解析

    这两天在学习beego框架,之前学习的时候遗漏了很多东西,比如orm.缓存.应用监控.模板处理等,这里将通过实例记录下如何使用beego自带的orm进行关联查询操作. 首先说明下,beego的orm有 ...

  9. Dos.ORM Select查询 自定义列

    自定义列 .Select( p = >new{ test = p.id}) // 同sql 列名 as 新列名 如下是 自己在写代码的例子,查询,分页,where条件,排序 var where ...

  10. laravel Eloquent ORM联合查询出现Class not found,就算在Moel中存在这个类

    今天发现一个坑,在处理Eloquent ORM的联合查询时,一直报错Class 'AdminGroup' not found ,可是我的项目中明明存在这个类,如下 这是我的模型类: 它们的控制器方法: ...

随机推荐

  1. 解决Android Studio运行时报Error:java.lang.NullPointerException (no error message)错误

    原文:解决Android Studio运行时报Error:java.lang.NullPointerException (no error message)错误                    ...

  2. 原 BinaryWriter和BinaryReader(二进制文件的读写)

    原文 BinaryWriter和BinaryReader(二进制文件的读写) C#的FileStream类提供了最原始的字节级上的文件读写功能,但我们习惯于对字符串操作,于是StreamWriter和 ...

  3. delphi文件操作(比较全)

    Delphi中默认有input和output两个文件变量,使用可以不用定义,直接使用. 但: input:只读.output:只写.用时注意以免引起异常. 文件是由文件名标识的一组数据的集合,文件通常 ...

  4. websocket协议学习

    一 实验代码 client.html websocket_server.go package main import ( "crypto/sha1" "encoding/ ...

  5. TIFF图片简介

    每个TIFF文件都是从指示字节顺序的两个字节开始的.“II”表示小字节在先.“MM”表示大字节在先字节顺序.后面的两个字节表示数字42.数字42是“为了其深刻的哲学意义"而选择的. 42的读 ...

  6. IT回忆录-1

    作为80后,差不多算是最开始一批接触互联网的人了.从用56K的猫拨号上网开始,不断地见证计算机和互联网的变化. 哥哥中考没考上,后来就去跟老师学计算机了.等他学完以后,我们家有了第一台电脑. 那个电脑 ...

  7. MySQL数据库MHA+keepalive实现

    MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀 ...

  8. win10 uwp 获得Slider拖动结束的值

    原文:win10 uwp 获得Slider拖动结束的值 本文讲的是如何获得Slider移动结束的值,也就是触发移动后的值.如果我们监听ValueChanged,在我们鼠标放开之前,只要拖动不放,那么就 ...

  9. TCP打洞和UDP打洞的区别 (相互直接访问)

    为什么网上讲到的P2P打洞基本上都是基于UDP协议的打洞?难道TCP不可能打洞?还是TCP打洞难于实现?     假设现在有内网客户端A和内网客户端B,有公网服务端S.     如果A和B想要进行UD ...

  10. XPath概述

    1.  XPath 具体示例可参考网址: http://www.zvon.org/xxl/XPathTutorial/General/examples.html 1.1 概述 * 现节点下所有元素 * ...