ORM的查询
基于对象的跨表查询(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"))
# 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的查询的更多相关文章
- Django的ORM常用查询操作总结(Django编程-3)
Django的ORM常用查询操作总结(Django编程-3) 示例:一个Student model: class Student(models.Model): name=models.CharFiel ...
- tornado 07 数据库—ORM—SQLAlchemy—查询
tornado 07 数据库—ORM—SQLAlchemy—查询 引言 #上节课使用query从数据库查询到了结果,但是query返回的对象是直接可用的吗 #在query.py内输入一下内容 from ...
- Django之ORM优化查询的方式
ORM优化查询的方式 一.假设有三张表 Room id 1 2 .. 1000 User: id 1 .. 10000 Booking: user_id room_id time_id date 1 ...
- Django orm进阶查询(聚合、分组、F查询、Q查询)、常见字段、查询优化及事务操作
Django orm进阶查询(聚合.分组.F查询.Q查询).常见字段.查询优化及事务操作 聚合查询 记住用到关键字aggregate然后还有几个常用的聚合函数就好了 from django.db.mo ...
- Net/NetCore/.NET5 ORM 六大查询体系 - SqlSugar 高级篇
框架介绍 SqlSugar ORM是一款老牌国产ORM框架,生命力也比较顽强,从早期ORM不成熟阶段,一直存活到现在,我为什么要一直坚持,那是因为还有很多用户在使用,本来我能够较早推出新开源框架 ,可 ...
- Moon.Orm 常见查询实例
一.Moon.Orm框架总述 (您还用hibernate?实体框架?) 1.框架名:Moon 意思是月亮,而非Mono.因为很喜欢明月,所以以此为名.它是一个.NET下的Orm框架. 2.发展历史:历 ...
- 我的ORM之一 -- 查询
我的ORM索引 概述 http://code.taobao.org/svn/MyOql/ 这是我自己写的开源ORM教程,我想先从场景示例中切入介绍,先有一个感性的认识,以小见大,触类旁通,有了这个认识 ...
- beego中orm关联查询使用解析
这两天在学习beego框架,之前学习的时候遗漏了很多东西,比如orm.缓存.应用监控.模板处理等,这里将通过实例记录下如何使用beego自带的orm进行关联查询操作. 首先说明下,beego的orm有 ...
- Dos.ORM Select查询 自定义列
自定义列 .Select( p = >new{ test = p.id}) // 同sql 列名 as 新列名 如下是 自己在写代码的例子,查询,分页,where条件,排序 var where ...
- laravel Eloquent ORM联合查询出现Class not found,就算在Moel中存在这个类
今天发现一个坑,在处理Eloquent ORM的联合查询时,一直报错Class 'AdminGroup' not found ,可是我的项目中明明存在这个类,如下 这是我的模型类: 它们的控制器方法: ...
随机推荐
- QuickReport的OnNeedData的触发情况
1.设置QuickReport的DataSet为空.2.在QuickReport的BeforePrint里面将要显示的数据集合初始化,如Query1.First;3.在OnNeedData里面写代码, ...
- 特殊存储过程——触发器Trigger
触发器类型 insert 触发器delete 触发器update 触发器 Inserted和Deleted两个临时表的作用 Inserted:对于插入记录操作来说,插入表里存放的是要插入的数据:对于更 ...
- DB First EF中的存储过程、函数、视图
视图约等于表(属性)存储过程变为方法,方法中调用存储过程 EF可以调用存储过程,DB First的流程是刷新模型,获取存储过程,调用参考:http://blog.csdn.net/sudazf/art ...
- WPF DataGrid支持的列类型
WPF DataGrid支持下面几种列类型: DataGridTextColumn DataGridCheckBoxColumn DataGridComboBoxColumn DataGridHype ...
- 【转】Powerdesigner逆向工程从sql server数据库生成pdm
第一步:打开"控制面板"中的"管理工具" 第二步:点击"管理工具"然后双击"数据源(odbc)" 第三步:打开之后,点击 ...
- 零元学Expression Blend 4 - Chapter 32 简单轻松的学会如何使用Visual States(上)
原文:零元学Expression Blend 4 - Chapter 32 简单轻松的学会如何使用Visual States(上) Visual State Manager中文翻译为视觉状态管理器,这 ...
- IT回忆录-1
作为80后,差不多算是最开始一批接触互联网的人了.从用56K的猫拨号上网开始,不断地见证计算机和互联网的变化. 哥哥中考没考上,后来就去跟老师学计算机了.等他学完以后,我们家有了第一台电脑. 那个电脑 ...
- Android零基础入门第69节:ViewPager快速实现引导页
在很多APP第一次启动时都会出现引导页,在一些APP里面还会包括一些左右滑动翻页和页面轮播切换的情况.在之前也已经学习了AdapterViewFlipper和ViewFlipper,都可以很好的实现, ...
- SimpleDateFormat之后为何多了一年,难道Java API也这么不靠谱?
这一切的背后到底是机器故障,还是程序的bug? 难道Java API也不靠谱 朋友在我博客上发现一时间明显错误,操作时间怎么会是2016年?在同一个for循环输出到页面的时间,唯独这一个时间不对,整整 ...
- autotools工具使用 good
学习GNU/LINUX开发的编程人员,上手之后不久就会在编译开源软件的时候碰到configure脚本,过段时间还会知道configure脚本是 autoconf生成的:但是真正想用起来autoconf ...