标签:reg 影响 -- import 外键 直接 方式 author nav
一、查询(重点)
正向查询和反向查询
关系属性(字段)写在哪个表里面,从当前类(表)的数据去查询它关联类(表)的数据叫做正向查询,反之叫做反向查询
正向查询
# 1.查询jiege的地址
author_obj = models.Author.objects.get(name=‘jiege‘)
print(author_obj.authorDetail.addr)
# 或者用filter这种查,但是要加.first()变成models对象,否则报错
author_obj1 = models.Author.objects.filter(name='jiege').first()
print(author_obj1.authorDetail.addr)
# 正向 author_obj.authorDetail 也就是 对象.关联属性名称
反向查询
# 2.查询 1996-02-14 是谁的生日
authordetail_obj = models.AuthorDetail.objects.get(birthday=‘1996-02-14‘)
print(authordetail_obj.author.name)
# 反向 authordetail_obj.author 也就是 对象.小写的另一个表名(类名)
总结
Author表 一对一关联 AuthorDetail表
正向查询:Authorobj.authorDetail,对象.关联属性名称
Author------------------------------------------------->AuthorDetail
<-------------------------------------------------
反向查询:AuthorDetailobj.author ,对象.小写类名
正向查询
# 1.查询 回村的诱惑 这本书是哪个出版社出版的
book_obj = models.Book.objects.get(title=‘回村的诱惑‘)
print(book_obj.publish.name)
# 正向 book_obj.publish 也就是 对象名.关联属性名称
反向查询
# 2.查询 外交出版社 都出版了哪些书
publish_obj = models.Publish.objects.get(name=‘外交出版社‘)
print(publish_obj.book_set.all()) # <QuerySet [<Book: yuhao的回忆录>, <Book: 杰哥你真猛>]>
print(publish_obj.book_set.all().filter(price__gt=500)) # <QuerySet [<Book: 杰哥你真猛>]>
# 反向 publish_obj.book_set 也就是 对象.表名小写_set
# 因为一个出版社可以对应很多书,所以用 book_set
# 因为结果返回一个queryset对象,可以继续加 .方法
总结
Book表 一对多关联 Publish表
正向查询:book_obj.publish,对象.关联属性名称
Book -------------------------------------------------> Publish
<-------------------------------------------------
反向查询:publish_obj.book_set.all(),对象.表名小写_set
正向查询
# 1.查询 yuhao的回忆录 这本书的作者都有谁
book_obj = models.Book.objects.get(title=‘yuhao的回忆录‘)
print(book_obj.authors.all()) # <QuerySet [<Author: jiege>, <Author: yuhao>, <Author: liangdao>]>
# 正向 book_obj.authors.all() 就是 对象.属性
反向查询
# 2.查询 liangdao 都写过哪些书
author_obj = models.Author.objects.get(name=‘liangdao‘)
print(author_obj.book_set.all()) # <QuerySet [<Book: yuhao的回忆录>, <Book: 装13是如何炼成的2>]>
# 反向 book_obj.author_obj.book_set.all() 就是 对象.表名小写_set
总结
Book表 多对多关联 Author表
正向查询:book_obj.authors.all(),对象.关联属性名称
Book -------------------------------------------------> Author
<-------------------------------------------------
反向查询:author_obj.book_set.all(),对象.表名小写_set
正向查询和反向查询
查询 jiege 的地址
# 方式1:正向查询
obj = models.Author.objects.filter(name=‘jiege‘).values(‘authorDetail__addr‘)
print(obj) # <QuerySet [{‘authorDetail__addr‘: ‘天空之城‘}]>
# 方式2:反向查询
obj1 = models.AuthorDetail.objects.filter(author__name='jiege').values('addr')
print(obj1) # <QuerySet [{'addr': '天空之城'}]>
哪个作者的生日是 2019 - 07 - 19
# 方式1:正向查询
obj = models.Author.objects.filter(authorDetail__birthday=‘2019-07-19‘).values(‘name‘)
print(obj) # <QuerySet [{‘name‘: ‘liangge‘}]>
# 方式2:反向查询
obj1 = models.AuthorDetail.objects.filter(birthday='2019-07-19').values('author__name')
print(obj1) # <QuerySet [{'author__name': 'liangge'}]>
查询一下 装13是如何炼成的 这本书的出版社是哪个
# 方式1:正向查询
obj = models.Book.objects.filter(title=‘装13是如何炼成的‘).values(‘publish__name‘)
print(obj) # <QuerySet [{‘publish__name‘: ‘膨胀出版社‘}]>
# 方式2:反向查询
obj1 = models.Publish.objects.filter(book__title='装13是如何炼成的').values('name')
print(obj1) # <QuerySet [{'name': '膨胀出版社'}]>
膨胀出版社 出版了哪些书
# 方式1:正向查询
obj = models.Book.objects.filter(publish__name=‘膨胀出版社‘).values(‘title‘)
print(obj)
# <QuerySet [{‘title‘: ‘装13是如何炼成的‘}, {‘title‘: ‘回村的诱惑‘}, {‘title‘: ‘装13是如何炼成的2‘}, {‘title‘: ‘杰哥诱惑‘}]>
# 方式2:反向查询
obj1 = models.Publish.objects.filter(name='膨胀出版社').values('book__title')
print(obj1)
# <QuerySet [{'book__title': '装13是如何炼成的'}, {'book__title': '回村的诱惑'}, {'book__title': '装13是如何炼成的2'}, {'book__title': '杰哥诱惑'}]>
杰哥诱惑 这本书是谁写的
# 方式1:正向查询
obj = models.Book.objects.filter(title=‘杰哥诱惑‘).values(‘authors__name‘)
print(obj) # <QuerySet [{‘authors__name‘: ‘yuhao‘}]>
# 方式2:反向查询
obj1 = models.Author.objects.filter(book__title='杰哥诱惑').values('name')
print(obj1) # <QuerySet [{'name': 'yuhao'}]>
yuhao 都写了哪些书
# 方式1:正向查询
obj = models.Book.objects.filter(authors__name=‘yuhao‘).values(‘title‘)
print(obj)
# <QuerySet [{‘title‘: ‘装13是如何炼成的‘}, {‘title‘: ‘yuhao的回忆录‘}, {‘title‘: ‘装13是如何炼成的2‘}, {‘title‘: ‘杰哥诱惑‘}]>
# 方式2:反向查询
obj1 = models.Author.objects.filter(name='yuhao').values('book__title')
print(obj1)
# <QuerySet [{'book__title': '装13是如何炼成的'}, {'book__title': 'yuhao的回忆录'}, {'book__title': '装13是如何炼成的2'}, {'book__title': '杰哥诱惑'}]>
装13出版社 出版的书的名称以及作者的名字
# 关联了三张表,Book、Author、publish
方式一:
obj = models.Publish.objects.filter(name='装13出版社').values('book__title','book__authors__name')
print(obj)
# <QuerySet [{'book__title': '回娘家的诱惑', 'book__authors__name': 'jiege'}, {'book__title': '回娘家的诱惑', 'book__authors__name': 'yuhao'}]>
方式二:
obj1 = models.Book.objects.filter(publish__name='装13出版社').values('title','authors__name')
print(obj1)
# <QuerySet [{'title': '回娘家的诱惑', 'authors__name': 'jiege'}, {'title': '回娘家的诱惑', 'authors__name': 'yuhao'}]>
方式三:
obj2 = models.Author.objects.filter(book__publish__name='装13出版社').values('book__title','name')
print(obj2)
# <QuerySet [{'book__title': '回娘家的诱惑', 'name': 'jiege'}, {'book__title': '回娘家的诱惑', 'name': 'yuhao'}]>
原生的sql语句是这样的:
SELECT
app01_book.title,
app01_author.name
FROM
app01_publish
INNER JOIN app01_book ON app01_publish.nid = app01_book.publish_id
INNER JOIN app01_book_authors ON app01_book.nid = app01_book_authors.book_id
INNER JOIN app01_author ON app01_author.nid = app01_book_authors.author_id
WHERE
app01_publish.name = ‘装13出版社‘;
使用Navicat工具:
手机号以4开头的作者出版过的所有书籍名称以及出版社名称
# 关联了四张表,Book、Author、publish、AuthorDetail
# 方式一
obj = models.AuthorDetail.objects.filter(telephone__startswith='4').values('author__book__title','author__book__publish__name')
print(obj)
# 方式二
obj1 = models.Book.objects.filter(authors__authorDetail__telephone__startswith='4').values('title','publish__name')
print(obj1)
# 方式三
obj2 = models.Publish.objects.filter(book__authors__authorDetail__telephone__startswith='4').values('book__title','name')
print(obj2)
# 方式四
obj3 = models.Author.objects.filter(authorDetail__telephone__startswith='4').values('book__title','book__publish__name')
print(obj3)
3.related_name
反向查询时,如果定义了related_name ,则用related_name替换 表名,
注意:,用在外键的创建 ForeignKey 中的一个参数,只会影响反向查询
例如:
# 在创建Book表的时候
class Book(models.Model):
......
publish=models.ForeignKey(to="Publish", to_field = "nid", on_delete = models.CASCADE,related_name='xx')
......
# 因为定义了related_name='xx',所以
# 在正向查询时,不会影响什么
# 在反向查询时,就不会用小写的表名了,而是必须用'xx',否则会报错
比如查询 装13是如何炼成的 这本书的出版社的名字
正向查询:
obj = models.Book.objects.filter(title='装13是如何炼成的').values('publish__name')
print(obj)
反向查询:
# 没加related_name='xx'
obj1 = models.Publish.objects.filter(book__title='装13是如何炼成的').values('name')
print(obj1)
# 加入了related_name='xx'
obj1 = models.Publish.objects.filter(xx__title='装13是如何炼成的').values('name')
print(obj1)
二、聚合查询
计算所有图书的平均价格、最高价格
from django.db.models import Avg,Max,Min,Count
obj = models.Book.objects.all().aggregate(a=Avg('price'),m=Max('price'))
print(obj) # {'a': 411.998571, 'm': Decimal('998.00')}
注意点:
标签:reg 影响 -- import 外键 直接 方式 author nav
原文地址:https://www.cnblogs.com/yangzm/p/11241117.html