55-56 ORM多表查询
Posted knighterrant
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了55-56 ORM多表查询相关的知识,希望对你有一定的参考价值。
多表查询:
KEY ====》 通过ORM引擎如何跨表: 正向查询按字段,反向查询按表名小写
模型的创建:
from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32) pub_date = models.DateField() price = models.DecimalField(max_digits=6,decimal_places=2) #publish 和book是一对多额关系 publish = models.ForeignKey(to="Publish",on_delete=models.CASCADE) #book和author 表示多对多关系 authors = models.ManyToManyField(to="Author",db_table="book2authors") def __str__(self): return self.title class Publish(models.Model): name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.CharField(max_length=32) def __str__(self): return self.name class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() #作者与作者详细信息时一对一关系 ad = models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) def __str__(self): return self.name class AuthorDetail(models.Model): brithday = models.DateField() tel = models.BigIntegerField() addr = models.CharField(max_length=64) def __str__(self): return str(self.tel)
一 基于对象的跨表查询( 子查询:以上一次的查询结果作为下一次的查询条件)
(1)一对多
正向查询:按字段 book.publish
Book对象 ---------------------------------- > Publish 对象
<---------------------------------
反向查询:按表名小写_set.all()
(2)多对多
正向查询:按字段 book.authors.all()
Book对象 ---------------------------------- > Author 对象
<---------------------------------
反向查询:按表名小写_set.all() ,#表名_set .all () 此处的set表示集合的意思
(3)一对一
正向查询:按字段 book.ad
Author 对象 ---------------------------------- > AuthorDetail 对象
<---------------------------------
反向查询:按表名小写
二 基于双下划綫的跨表查询:(相当于 mysql 中的 join)
left join on
通过 表名__该表名字段=“ 条件 ” , 表名__ 表示连表
结构: models.Book.objects.filter(条件).values(需要查询的字段)
#多表操作======》添加def add(request):
###############################绑定一对多关系############################################################ #方式一 # book = models.Book.objects.create(title="python", price=123, pub_date="2019-01-02", publish_id=1) pub_obj = models.Publish.objects.filter(name="苹果出版社").first() # # book = models.Book.objects.create(title="python",price=123,pub_date="2019-01-02",publish=pub_obj) # print(book.title) #python # print(book.publish_id) #2 # print(book.publish)#苹果出版社,打印对象时,__str__ 返回的值 # 查询go出版社的邮箱 # book_go = models.Book.objects.filter(title="go").first() # print(book_go.publish.email) #############################绑定多对多关系,无非是在关系表中创建记录###################################### # linux这本书绑定两个作者:alex,egon linux = models.Book.objects.filter(title="linux").first() alex = models.Author.objects.filter(name="alex").first() egon = models.Author.objects.filter(name="egon").first() # linux.authors.add(alex.id,egon.id) #为什么不是这样写 # linux.authors.add(alex,egon) #重复的作者不会添加,不知道主键时用这种方式添加 # linux.authors.add(1,2) #这个也可以,已经知道主键用这种方式添加 # linux.authors.add(*[2,1])#相当于打散,一个个赋值 # linux.authors.remove(egon) #移除 # linux.authors.clear() 解除所有绑定 # linux.authors.set(1) #不能这样写 # linux.authors.set([1,]) #先清空,再添加,参数必须为一个列表 # # 绑定多对多的方式:一定要找到关联属性在哪里,manytomany 关联属性authors, # book.关联属性.add() book.关联属性.set([,]),book.关联属性.clear() #正向操作(关联字段所在的那个表开始)按字段,反向操作按表名小写 #给Alex添加两个书 linux = models.Book.objects.filter(title="linux").first() go = models.Book.objects.filter(title="go").first() alex = models.Author.objects.filter(name="alex").first() #给Alex 作者绑定两本书籍:linux和go alex.book_set.add(linux,go) return HttpResponse("添加成功!") # 一对一表的添加和一对多类似 作者表和作者详细表 #多表操作========》查询
def query(request): ##################################################基于对象的跨表查询############################################ # (1) 一对多 #1 查询linux 这本书籍的出版社的地址
正向查询
# linux = models.Book.objects.filter(title="linux").first() # print(linux.publish.city) # 2 查询苹果出版社出版的所有书籍
反向查询
# obj = models.Publish.objects.filter(name="苹果出版社").first() # query = obj.book_set.all() # print(query) # (2) 多对多 # 1 查询linux书籍的所有作者 # linux = models.Book.objects.filter(title="linux").first() # print(linux.authors.all()) # 2查询alex作者出版过得所有书籍 # alex = models.Author.objects.filter(name="alex").first() # print(alex.book_set.all()) # (3)一对一 # 1 查询alex的手机号 # alex = models.Author.objects.filter(name="alex").first() # print(alex.ad.tel) # 2 查询手机号为911的作者的名字 # obj = models.AuthorDetail.objects.filter(tel=911).first() # print(obj.authors.name) ###########################################基于双下划线的跨表查询################################################## # 1 查询linux这本书籍的出版社的地址 # 方式一 # queryset = models.Book.objects.filter(title="linux").values("publish__city") # print(queryset) # print(queryset[0]["publish__city"]) # return HttpResponse("查询成功!") #方式二 # queryset = models.Publish.objects.filter(book__title="linux").values("city") # print(queryset) # return HttpResponse("查询成功") # 2 查询linux书籍的所有作者 #正向查询 # queryset = models.Book.objects.filter(title="linux").values("authors__name") # print(queryset) #反向查询 # queryset = models.Author.objects.filter(book__title="linux").values("name") # print(queryset) # 3 查询alex的手机号 #正向查询 # queryset = models.Author.objects.filter(name="alex").values("ad__tel") # print(queryset) #反向查询 # queryset = models.AuthorDetail.objects.filter(author__name="alex").values(‘tel‘) # print(queryset) # 连续跨表 # 4 查询人民出版社出版过的所有书籍的名字以及作者的姓名 # queryset = models.Book.objects.filter(publish__name="人民出版社").values("title","authors__name") # print(queryset) # queryset = models.Author.objects.filter(book__publish__name="人民出版社").values("book__title","name") # print(queryset) # 5 手机号以119开头的作者出版过的所有书籍名称以及出版社名称 queryset = models.Book.objects.filter(authors__ad__tel__startswith=119).values("title","publish__name") print(queryset) return HttpResponse("查询成功")
待续
以上是关于55-56 ORM多表查询的主要内容,如果未能解决你的问题,请参考以下文章
[Django框架之ORM操作:多表查询,聚合查询分组查询F查询Q查询choices参数]
python 之 Django框架(orm单表查询orm多表查询聚合查询分组查询F查询 Q查询事务Django ORM执行原生SQL)