06-模型层5—多表操作之进阶练习:连续跨表与related_name
例1
查询地址以'as'开头的作者出版过的所有书籍名称以及书籍的出版社名称
(1)
通过Book表join表AuthorDetail,但Book与AuthorDetail无关联,因此必须以Author为桥梁连续跨表:
##注意这里是 value_list
ret = Book.objects.filter(authors__authordetail__addr__startswith='as').values('title','publish__name')
print(ret) #<QuerySet [{'title': '三国群英', 'publish__name': '333'}]>
(2)
以Author表为基准,它与AuthorDetail表有关联,但是与Publish无关联,因此得以Book表为桥梁
ret = Author.objects.filter(authordetail__addr__startswith='as').values('book__title','book__publish__name')
print(ret) #<QuerySet [{'book__title': '三国群英', 'book__publish__name': '333'}]>
例2
查询人民出版社出版过的所有书籍的名字以及作者的姓名
(1)正向查询
##Book相对于Publish与Author都是“正向的”
##注意用 values_list
ret = Book.objects.filter(publish__name='人民出版社').values_list('title','authors__name')
print(ret)
(2)反向查询
过程说明
A_首先,filter等价于where,我们以Publish为基准查,因此filter里直接写name='人民出版社'即可;
B_然后,由于Publish跟Author没有直接联系,我们得借助Book作为桥梁:
(B1)要找书籍的名字,由于Publish查Book是反向查询,“用表明小写”————因此“书籍名字”是 book__title
(B2)而要找作者名字,由于Book找Author是正向查询,“用字段”————因此“在Book的基础上”我们用:book__authors__name。
查询语句
##注意用 values_list
ret = Publish.objects.filter(name='人民出版社').values__list('book__title','book__authors__name')
print(ret)
related_name
“反向查询”时,如果定义了related_name ,则用related_name替换表名
例如在Book中这样定义:
publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True,related_name='booklist')
那么:查询人民出版社出版过的所有书籍的名字与价格(一对多)
(1)正向查询————“用不到”
ret = Book.objects.filter(publish__name='人民出版社').values('title','price')
print(ret)
(2)反向查询——
ret = Publish.objects.filter(name='人民出版社').values('booklist__title','booklist__price')