Loading

Django之ORM多表查询

ORM多表查询

多表查询一定涉及到外键。

多表也叫跨表查询,肯定有where语句,否则出现笛卡尔集现象,那么表之间的关系就靠外键来建立的。

正反向概念

正向

书和出版社多对一的关系,由书查publish,外键字段在书上,那么就是正向。

反向

反之用出版社查书,外键在书上,那么就是反向

总之:查对方的时候,如果外键在你手上就是正向,反之反向。

记住:正向查询按字段,反向查询按表名小写。

因为正向时主体手里有外键字典,你点此字段就意味着要跨表。

而反向时,点不出来外键字段,点表名就意味着你要连此表。

基于对象的跨表查询

核心:怎么跨表?

子查询(基于对象的跨表查询)

1.查询主键为1的出版社名称。
select publish_name from publish where pid=(select publish_id from book where id = 1)
orm用正反向的总结直接跨表,正向按字段,反向按表名小写,完成跨表!! book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish.publish_name

2.查询书籍pk=1的作者,书和作者一对一,外键在书上
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.all() # 这里作者有多本书时,要all(),当只有一个数据的时候不需要all()

3.作者json的电话号码,仍然正向
author_obj = models.Author.objects.filter(name="jaon").fitst()
res = author_obj.author_detail # 拿到的都是对象,即一行记录
res.phone # 即可拿到电话

 

4.查询东方出版社出版的书
publish_obj = models.Publish.objects.filter(name="东方出版社”).first()
publish_obj.book_set.all()
5.作者json写过的书
author_obj = models.Author.filter(name="json").first()
book = author_obj.book_set.all()
6.手机号为11111的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=11111).first()
res = author_detail_obj.author # 这里不需要加_set
print(res.name)
总结:什么时候需要加_set.all()
当结果有多个时需要加,只有一个的时候不需要加

基于双下划线的跨表查询

刚才是基于对象进行跨表,接下来用双下划线。但是都是两行代码,先查到一个对象,之后再查询。

连表查询(基于双下滑线的跨表查询)

要求:只能一行代码实现跨表查询

1.查询json 的手机号,并显示json的名字。  正向查询按字段
res=models.Author.objects.filter(name="json").values("author_detail_ _phone",“name”) # author_detail表示跨表到哪里,后面的__表示要什么字段的值
反向:res=models.AuthorDetail.objects.filter(author__name="json").values("phone","author__name")
没有再像前面放到外面点,而是用values方法,将表与字段以参数的形式传入
models点的谁,后面操作的基表就是谁,那么直接“name”即可
2.查询书籍pk=1的竖版社名和书的名称,正向直接外键字段,publish就跨表了,要什么字段__取就可以了
res = models.Book.obejcts.filter(pk=1).values("publish_ _name","title")

3.查询json 的手机号,并显示json的名字,不允许.Author,只能强行反向。
res= models.AuthorDetail.objects.filter(author__name="json") #拿作者为json的作者详情,filter也支持正向反向
res= models.AuthorDetail.objects.filter(author__name="json") .values("pbone","author__name")
filter内的关键字参数的key,前面代表要跨什么表,双下滑后面表示你要查什么字段=后面的值
而values方法是对最终结果字段以及跨表的字段值过滤。

总结:可以一个模板下来,自由的控制正反向,只要控制参数就可以了。

 

跨n个表呢?!

查书籍pk=1的作者的手机号,跨了书籍表、作者表、作者详情表,  书和作者详情没有关系,与作者有关只能先跨到作者,再跨到作者详情表

res=models.Book.objects.filter(pk=1).values("authors_ _authors_detail_ _phone”)

 

 

 

 

 

ORM多表查询

posted @ 2021-04-28 17:16  浅忆尘  阅读(271)  评论(0编辑  收藏  举报