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多表查询
看十遍不如自己写一遍!巩固基础,纵横开拓!