Django 的 orm 查询
一.模型关系表
1. 一对一
Author-AuthorDetail
关联字段可以在任意表下,但必须唯一约束。(unique约束)
ad_id(unique约束) ad = models.oneToOneField("AuthorDetail",null=True,on_delete=models.CASCADE) 相当于 authors = models.ForgeinKey(to="Author",on_delete=models.CASCADE,unique) 2. 一对多
publish-book 关联字段在“多”的表中
建立ForgeinKey 约束 3. 多对多
book-author
关系表
foreinkey book_id references Book(id)
foreinkey author_id references Author(id)
authors = models.ManyToManyField("Author") 二.多表查询
a.一定要知道mysql 语句
b.增删改查
=========================================================================================================================
1. 添加
create
添加记录的思路:考虑 三种关系表的特殊字段
Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1) #数据库级别 def add(request):
======================绑定一对多关系=========================================== #一对多:(publish-book)
方式一: Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1) 方式二:
pub_obj = Publish.objects.filter(name= "苹果出版社").first()
Book.objects.create(title="python",price=123,pub_date = "2012-11-12",publish=pub_obj) python = Book.objects.filter(title="python").first() python.publish #得到的是python这本书对应的出版社对象 ===================绑定多对多关系:无非是在第3张关系表中创建记录===================== 正向操作按字段,反向操作按表名小写 #多对多:(authors-book)
key:一定要找到多对多关联属性在哪张表下,如Book下的authors,先找到book对象,再用该书籍对象
点关联字段 1.给python这本书绑定两个作者:alex egon
python = Book.objects.filter(title="python").first()
alex = Author.objects.filter(name="alex").first()
egon = Author.objects.filter(name="egon").first() python.authors.add(alex,egon)
python.authors.add(1,2) #1,2分别为alex,egon的主键
python.authors.add(*[1,2,3,4,5]) #打散传
python.authors.remove(alex,egon)
python.authors.clear() #解除所有绑定
python.authors.set([1,]) #先清空,在赋值操作 2. 给alex作者绑定两本书籍 python和linux alex = Author.objects.filter(name="alex").first()
python= Book.objects.filter(title="python").first()
linux= Book.objects.filter(title="linux").first() alex.book_set.add(alex,linux) ========================================================================================================================== 2.查询
def queryset(request): ===============================基于对象的跨表查询================================ 基于对象的跨表查询:(sql语句 子查询:以上一次的查询结果作为下一次的查询条件)
1.一对多:
正向查询按字段publish linux.publish
Book----------------------------------------------Publish
反向查询按表名小写_set.all() 1.查询linux这本书籍出版社的邮箱
linux = Book.objects.filter(title="linux").first()
print(linux.publish.emial) 2.查询苹果出版社出版的所有书籍
p1 = Publish.objects.filter(name="苹果出版社").first()
queryset = p1.book_set.all() 2. 多对多:
正向查询按字段authors book_obj.authors.all()
Book---------------------------------------------------Author
反向查询按表名小写_set().all() 1.查询linux这本书所有作者
linux= Book.objects.filter(title="linux").first()
queryset = linux.authors.all() 2.查询作者alex出版过的所有书籍 alex = Author.objects.filter(name="alex").first()
queryset = alex.book_set.all() 3. 一对一:
正向查询按字段ad, author_obj.ad
Author--------------------------------------------AuthorDetail
反向查询按表名小写 Authordetail_obj.author 1.查询alex手机号
alex= Author.objects.filter(name="alex").first()
alex.ad.telphone 2.查询手机号为123的作者
ad_obj = AuthorDetail.objects.filter(telphone=123).first()
print(ad_obj.author.name) =================================基于双下滑线的跨表查询(join查询)======================================= 把多张表合成一张表,按单表查。
key: 通知orm引擎,进行跨表,正向查询按表名,反向查询按表名小写 1.一对多 1.查询linux这本书籍出版社的邮箱 sql :
select email from book inner join publish on book.publish_id = publish.id where book.title='linux' orm :(values 显示查询字段)
#方式一
queryset = Book.objects.filter(title="linux").values("publish__email")
#方式二
queryset = Publish.objects.filter(book__title = "linux").value("email") 2.多对多
1.查询linux这本书的所有作者名字
sql:
select author.name from book left join book2authors on book.id = book2authors.book_id
left join author on author.id = book2authors.author_id
where book.title="linux"
orm:
方式一:
queryset = Book.objects.filter(title="linux").values("authors__name")
left join 显示左边表中所有的数据
inner join如果基表没有数据就不显示第二个表中的那部分数据
方式二: queryset = Author.objects.filter(book__title="linux").values('name') 3. 一多一
1.查询alex手机号
方式一:
queryset = Author.objects.filter(name="alex").values("ad__telphone")
方式二:
queryset = AuthorDetail.objects.filter(author__name="alex").values("telphone") 4.连续跨表查询
1.查询人民出版社出版过的所有书籍名称以及作者名字 Publish.objects.filter(name="人民出版社").values("book__name","book__authors__name")
Book.objects.filter(publish__name="人民出版社").values("name","authors__name") 2.手机号以151开头的作者出版过的所有书籍名称以及所有出版社名称
Author.objects.filter(ad__telphone__startswith=151).values("book__name","book__publish__name") ================================聚合和分组查询============================================ 1.聚合(aggregate 只对一组进行统计) from django.db.models import Avg,Count,Max,Min 1.计算所有图书的平均价格
Book.objects.all().aggregate(avg_price=Avg("price"))
2. 计算所有图书的最高价和最低价
Book.objects.all().aggregate(min_price=Min("price"),max_price=Max('price')) 2.分组查询 (annotate 对多组数据进行统计) 1.单表分组:
emp
id name salary dep province
1 alex 20000 销售部 山东
2 egon 30000 人事部 河北
3 wang 40000 人事部 山东 查询 : 每个部门的名称以及员工人数 sql:
select dep,Count(*) from emp group by dep;
select dep,Avg(salary) from emp group by dep; orm:
按哪个字段group by 就 values 哪个字段,用annotate 统计
1.查询每个部门的名字
queryset = Emp.objects.values("dep").annotate(c=Count("*"))
2.查询每个省份的平均薪水
queryset= Emp.objects.values("province").annotate(avg_salary=Avg("salary")) 2.多表分组:(多张关联表)
key:多张表join起来,再按单表查
1.查询每个出版社的名称以及出版过书籍的平均价格
sql:
select publish.name,Avg(book.price) from publish left join book on publish.id = book.publish_id
group by publish.id,publish.name orm:
方式一:
queryset = Publish.objects.values("name","id").annotate(avg_price =avg("book__price"))
方式二:
queryset = Publish.objects.all().annotate(avg_price =avg("book__price")) 2.查询每一个作者的名字以及出版书籍的个数
方式一:
queryset = Author.objects.values("name").annotate(book_num=Count("book"))
方式二:
queryset = Author.objects.annotate(book_num=Count("book")).values("book_num","name") 3.查询每本书籍名称以及作者个数
queryset = Book.objects.annotate(c=Count("authors")).values("title",c) 4.查询作者个数大于1的书籍名称和作者个数
sql:
select book.tilte,Count(author.id) as c from book left join book2authors on book.id = book2authors.book_id
left join Author on book2authors.author_id
group by book.id
having c>1
orm:
queryset = Book.objects.annotate(c=Count("authors")).filter(c__gt=1).values("title","c")
(相当于having) 5.查询书籍名称包含“h"的书籍名称和作者个数
Book.objects.filter(title__icontains='h').annonate(c=Count('authors')).values("title",c)
(相当于where) ====================================F查询和Q查询=================================================== from django.db.models import F,Q,Avg 1.F查询 1.查询评论数大于100的文章
Article.objects.filter(comment_num__gt=100)
2.查询评论数大于点赞数的文章
Article.objects.filter(comment_num__gt=F(poll_num))
3.查询评论数大于100的所有文章 queryset = Article.objects.filter(comment_num__gt=F("poll_num")*2)
4.将所有书籍的价格提高一百元
Book.objects.update(price=F("price")+100) 2.Q查询 (|或 &且 ~非)
1.查询价格大于200或名称以"p"开头的书籍
queryset = Book.objects.all().filter(Q(price__gt=200)|Q(title__startswith="p")
2.查询价格大于300或出版日期(不是)为2019年一月份的书籍 queryset= Book.objects.filter(Q(price__gt=300)|~Q(Q(pub_date_year=2019)&Q(pub_date_month=1)))
一.模型关系表
1. 一对一
Author-AuthorDetail
关联字段可以在任意表下,但必须唯一约束。(unique约束)
ad_id(unique约束) ad = models.oneToOneField("AuthorDetail",null=True,on_delete=models.CASCADE) 相当于 authors = models.ForgeinKey(to="Author",on_delete=models.CASCADE,unique) 2. 一对多
publish-book 关联字段在“多”的表中
建立ForgeinKey 约束 3. 多对多
book-author
关系表
foreinkey book_id references Book(id)
foreinkey author_id references Author(id)
authors = models.ManyToManyField("Author") 二.多表查询 a.一定要知道mysql 语句
b.增删改查
=========================================================================================================================
1. 添加
create
添加记录的思路:考虑 三种关系表的特殊字段
Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1) #数据库级别 def add(request):
======================绑定一对多关系=========================================== #一对多:(publish-book)
方式一: Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1) 方式二:
pub_obj = Publish.objects.filter(name= "苹果出版社").first()
Book.objects.create(title="python",price=123,pub_date = "2012-11-12",publish=pub_obj) python = Book.objects.filter(title="python").first() python.publish #得到的是python这本书对应的出版社对象 ===================绑定多对多关系:无非是在第3张关系表中创建记录===================== 正向操作按字段,反向操作按表名小写 #多对多:(authors-book)
key:一定要找到多对多关联属性在哪张表下,如Book下的authors,先找到book对象,再用该书籍对象
点关联字段 1.给python这本书绑定两个作者:alex egon
python = Book.objects.filter(title="python").first()
alex = Author.objects.filter(name="alex").first()
egon = Author.objects.filter(name="egon").first() python.authors.add(alex,egon)
python.authors.add(1,2) #1,2分别为alex,egon的主键
python.authors.add(*[1,2,3,4,5]) #打散传
python.authors.remove(alex,egon)
python.authors.clear() #解除所有绑定
python.authors.set([1,]) #先清空,在赋值操作 2. 给alex作者绑定两本书籍 python和linux alex = Author.objects.filter(name="alex").first()
python= Book.objects.filter(title="python").first()
linux= Book.objects.filter(title="linux").first() alex.book_set.add(alex,linux) ========================================================================================================================== 2.查询
def queryset(request): ===============================基于对象的跨表查询================================ 基于对象的跨表查询:(sql语句 子查询:以上一次的查询结果作为下一次的查询条件)
1.一对多:
正向查询按字段publish linux.publish
Book----------------------------------------------Publish
反向查询按表名小写_set.all() 1.查询linux这本书籍出版社的邮箱
linux = Book.objects.filter(title="linux").first()
print(linux.publish.emial) 2.查询苹果出版社出版的所有书籍
p1 = Publish.objects.filter(name="苹果出版社").first()
queryset = p1.book_set.all() 2. 多对多:
正向查询按字段authors book_obj.authors.all()
Book---------------------------------------------------Author
反向查询按表名小写_set().all() 1.查询linux这本书所有作者
linux= Book.objects.filter(title="linux").first()
queryset = linux.authors.all() 2.查询作者alex出版过的所有书籍 alex = Author.objects.filter(name="alex").first()
queryset = alex.book_set.all() 3. 一对一:
正向查询按字段ad, author_obj.ad
Author--------------------------------------------AuthorDetail
反向查询按表名小写 Authordetail_obj.author 1.查询alex手机号
alex= Author.objects.filter(name="alex").first()
alex.ad.telphone 2.查询手机号为123的作者
ad_obj = AuthorDetail.objects.filter(telphone=123).first()
print(ad_obj.author.name) =================================基于双下滑线的跨表查询(join查询)======================================= 把多张表合成一张表,按单表查。
key: 通知orm引擎,进行跨表,正向查询按表名,反向查询按表名小写 1.一对多 1.查询linux这本书籍出版社的邮箱 sql :
select email from book inner join publish on book.publish_id = publish.id where book.title='linux' orm :(values 显示查询字段)
#方式一
queryset = Book.objects.filter(title="linux").values("publish__email")
#方式二
queryset = Publish.objects.filter(book__title = "linux").value("email") 2.多对多
1.查询linux这本书的所有作者名字
sql:
select author.name from book left join book2authors on book.id = book2authors.book_id
left join author on author.id = book2authors.author_id
where book.title="linux"
orm:
方式一:
queryset = Book.objects.filter(title="linux").values("authors__name")
left join 显示左边表中所有的数据
inner join如果基表没有数据就不显示第二个表中的那部分数据
方式二: queryset = Author.objects.filter(book__title="linux").values('name') 3. 一多一
1.查询alex手机号
方式一:
queryset = Author.objects.filter(name="alex").values("ad__telphone")
方式二:
queryset = AuthorDetail.objects.filter(author__name="alex").values("telphone") 4.连续跨表查询
1.查询人民出版社出版过的所有书籍名称以及作者名字 Publish.objects.filter(name="人民出版社").values("book__name","book__authors__name")
Book.objects.filter(publish__name="人民出版社").values("name","authors__name") 2.手机号以151开头的作者出版过的所有书籍名称以及所有出版社名称
Author.objects.filter(ad__telphone__startswith=151).values("book__name","book__publish__name") ================================聚合和分组查询============================================ 1.聚合(aggregate 只对一组进行统计) from django.db.models import Avg,Count,Max,Min 1.计算所有图书的平均价格
Book.objects.all().aggregate(avg_price=Avg("price"))
2. 计算所有图书的最高价和最低价
Book.objects.all().aggregate(min_price=Min("price"),max_price=Max('price')) 2.分组查询 (annotate 对多组数据进行统计) 1.单表分组:
emp
id name salary dep province
1 alex 20000 销售部 山东
2 egon 30000 人事部 河北
3 wang 40000 人事部 山东 查询 : 每个部门的名称以及员工人数 sql:
select dep,Count(*) from emp group by dep;
select dep,Avg(salary) from emp group by dep; orm:
按哪个字段group by 就 values 哪个字段,用annotate 统计
1.查询每个部门的名字
queryset = Emp.objects.values("dep").annotate(c=Count("*"))
2.查询每个省份的平均薪水
queryset= Emp.objects.values("province").annotate(avg_salary=Avg("salary")) 2.多表分组:(多张关联表)
key:多张表join起来,再按单表查
1.查询每个出版社的名称以及出版过书籍的平均价格
sql:
select publish.name,Avg(book.price) from publish left join book on publish.id = book.publish_id
group by publish.id,publish.name orm:
方式一:
queryset = Publish.objects.values("name","id").annotate(avg_price =avg("book__price"))
方式二:
queryset = Publish.objects.all().annotate(avg_price =avg("book__price")) 2.查询每一个作者的名字以及出版书籍的个数
方式一:
queryset = Author.objects.values("name").annotate(book_num=Count("book"))
方式二:
queryset = Author.objects.annotate(book_num=Count("book")).values("book_num","name") 3.查询每本书籍名称以及作者个数
queryset = Book.objects.annotate(c=Count("authors")).values("title",c) 4.查询作者个数大于1的书籍名称和作者个数
sql:
select book.tilte,Count(author.id) as c from book left join book2authors on book.id = book2authors.book_id
left join Author on book2authors.author_id
group by book.id
having c>1
orm:
queryset = Book.objects.annotate(c=Count("authors")).filter(c__gt=1).values("title","c")
(相当于having) 5.查询书籍名称包含“h"的书籍名称和作者个数
Book.objects.filter(title__icontains='h').annonate(c=Count('authors')).values("title",c)
(相当于where) ====================================F查询和Q查询=================================================== from django.db.models import F,Q,Avg 1.F查询 1.查询评论数大于100的文章
Article.objects.filter(comment_num__gt=100)
2.查询评论数大于点赞数的文章
Article.objects.filter(comment_num__gt=F(poll_num))
3.查询评论数大于100的所有文章 queryset = Article.objects.filter(comment_num__gt=F("poll_num")*2)
4.将所有书籍的价格提高一百元
Book.objects.update(price=F("price")+100) 2.Q查询 (|或 &且 ~非)
1.查询价格大于200或名称以"p"开头的书籍
queryset = Book.objects.all().filter(Q(price__gt=200)|Q(title__startswith="p")
2.查询价格大于300或出版日期(不是)为2019年一月份的书籍 queryset= Book.objects.filter(Q(price__gt=300)|~Q(Q(pub_date_year=2019)&Q(pub_date_month=1)))
代码
Django 的 orm 查询的更多相关文章
- Django之ORM查询复习与cookie
ORM查询总结: models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwa ...
- Django之ORM查询
ORM 映射关系: 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象图书管理系统的增删改查:代码如下:views ...
- [django]django的orm查询
实体 实体 出版社 category 作者 tag 书 文章 先学习一下基础的增删查改 django orm增删改查: https://www.cnblogs.com/iiiiiher/article ...
- Django之ORM查询进阶
基于双下划线的双表查询 分组与聚合函数 基于双下划线的双表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询, ...
- django优化--ORM查询
ORM提供了两个方法用来优化查询效率 1. select_related 有两张表:表结构如下: class Scheme(models.Model): """ 套餐类 ...
- Django之ORM查询操作详解
浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Python脚本中调用Django环境 其他操 ...
- Django 源码小剖: Django ORM 查询管理器
ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...
- Django ORM 查询管理器
Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...
- Django的ORM常用查询操作总结(Django编程-3)
Django的ORM常用查询操作总结(Django编程-3) 示例:一个Student model: class Student(models.Model): name=models.CharFiel ...
随机推荐
- 赞 ( 84 ) 微信好友 新浪微博 QQ空间 180 SSD故事会(14):怕TLC因为你不了解!【转】
本文转载自:https://diy.pconline.com.cn/750/7501340.html [PConline 杂谈]从前,大家谈TLC色变:如今,TLC攻占SSD半壁江山.是的,这个世界就 ...
- P3380 【模板】二逼平衡树(树套树)
思路 若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名 若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数 若opt=3 则为操作 ...
- 题解——P1133 教主的花园DP
直接设二维状态具有后效性,会爆零 然后需要加一维 然后70 看了题解之后发现没有考虑1和n的关系 考虑之后,四十 然后懵逼 突然发现自己的ans更新写错了,导致每次ans都是第一个取30的情况的解 然 ...
- AngularJS 笔记2
2017-03-23 本文更新链接: http://www.cnblogs.com/daysme/p/6613071.html $http angularjs中的ajax 向服务器请求数据 1/2 后 ...
- HDU 4325 Flowers(树状数组+离散化)
http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...
- JsonKey小写
System.Text.RegularExpressions.MatchCollection ms = System.Text.RegularExpressions.Regex.Matches(eca ...
- [原]windows sdk版本不对
系统硬盘换了,重新安装一堆软件,SVN. 之前的SVN地址直接能找到 在编译vs项目的时候出现问题: windows sdk 10.0.14393.0 版本找不到 发现自己按照vs时候更新不了最新sd ...
- C#6.0 语法
属性表达式 属性值初始化 public string name {get;set;} = "张三"; 函数表达式 NULL检查运算符 var aa = Created?.Date; ...
- vscode所用插件
- SpringMVC获取页面表单参数的几种方式
以下几种方式只有在已搭好的SpringMVC环境中,才能执行成功! 首先,写一个登陆页面和一个Bean类 <%@ page language="java" co ...