基于双下划线的跨表查询
Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止。
'''
正向查询按字段,反向查询按表名小写用来告诉ORM引擎join哪张表
'''
一对多查询
# 练习: 查询苹果出版社出版过的所有书籍的名字与价格(一对多)
# 正向查询 按字段:publish
queryResult=Book.objects
.filter(publish__name="苹果出版社")
.values_list("title","price")
# 反向查询 按表名:book
queryResult=Publish.objects
.filter(name="苹果出版社")
.values_list("book__title","book__price")
查询的本质一样,就是select from的表不一样
# 正向查询按字段,反向查询按表名小写
# 查询红楼梦这本书出版社的名字
# select * from app01_book inner join app01_publish
# on app01_book.publish_id=app01_publish.nid
ret=Book.objects.filter(name='红楼梦').values('publish__name')
print(ret)
ret=Publish.objects.filter(book__name='红楼梦').values('name')
print(ret)
多对多查询
# 练习: 查询alex出过的所有书籍的名字(多对多)
# 正向查询 按字段:authors:
queryResult=Book.objects
.filter(authors__name="yuan")
.values_list("title")
# 反向查询 按表名:book
queryResult=Author.objects
.filter(name="yuan")
.values_list("book__title","book__price")
# -------多对多正向查询
# 查询红楼梦所有的作者
ret=Book.objects.filter(name='红楼梦').values('authors__name')
print(ret)
# ---多对多反向查询
ret=Author.objects.filter(book__name='红楼梦').values('name')
ret=Author.objects.filter(book__name='红楼梦').values('name','author_detail__addr')
print(ret)
# 正向查询按字段,反向查询按表名小写
# 查询红楼梦这本书出版社的名字
# select * from app01_book inner join app01_publish
# on app01_book.publish_id=app01_publish.nid
ret=Book.objects.filter(name='红楼梦').values('publish__name')
print(ret)
ret=Publish.objects.filter(book__name='红楼梦').values('name')
print(ret)
# sql 语句就是from的表不一样
# -------多对多正向查询
# 查询红楼梦所有的作者
ret=Book.objects.filter(name='红楼梦').values('authors__name')
print(ret)
# ---多对多反向查询
ret=Author.objects.filter(book__name='红楼梦').values('name')
ret=Author.objects.filter(book__name='红楼梦').values('name','author_detail__addr')
print(ret)
一对一查询
# 查询alex的手机号
# 正向查询
ret=Author.objects.filter(name="alex").values("authordetail__telephone")
# 反向查询
ret=AuthorDetail.objects.filter(author__name="alex").values("telephone")
# 查询lqz的手机号
# 正向查
ret=Author.objects.filter(name='lqz').values('author_detail__telephone')
print(ret)
# 反向查
ret= AuthorDatail.objects.filter(author__name='lqz').values('telephone')
print(ret)
进阶练习(连续跨表)
# 练习: 查询人民出版社出版过的所有书籍的名字以及作者的姓名
# 正向查询
queryResult=Book.objects
.filter(publish__name="人民出版社")
.values_list("title","authors__name")
# 反向查询
queryResult=Publish.objects
.filter(name="人民出版社")
.values_list("book__title","book__authors__age","book__authors__name")
# 练习: 手机号以151开头的作者出版过的所有书籍名称以及出版社名称
# 方式1:
queryResult=Book.objects
.filter(authors__authorDetail__telephone__regex="151")
.values_list("title","publish__name")
# 方式2:
ret=Author.objects
.filter(authordetail__telephone__startswith="151")
.values("book__title","book__publish__name")
# ----进阶练习,连续跨表
# 查询手机号以33开头的作者出版过的书籍名称以及书籍出版社名称
# author_datail author book publish
# 基于authorDatail表
ret=AuthorDatail.objects.filter(telephone__startswith='33').values('author__book__name','author__book__publish__name')
print(ret)
# 基于Author表
ret=Author.objects.filter(author_detail__telephone__startswith=33).values('book__name','book__publish__name')
print(ret)
# 基于Book表
ret=Book.objects.filter(authors__author_detail__telephone__startswith='33').values('name','publish__name')
print(ret)
# 基于Publish表
ret=Publish.objects.filter(book__authors__author_detail__telephone__startswith='33').values('book__name','name')
print(ret)
related_name
publish = ForeignKey(Blog, related_name='bookList')
反向查询时,如果定义了related_name ,则用related_name替换表名,例如:
# 练习: 查询人民出版社出版过的所有书籍的名字与价格(一对多)
# 反向查询 不再按表名:book,而是related_name:bookList
queryResult=Publish.objects
.filter(name="人民出版社")
.values_list("bookList__title","bookList__price")