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多表查询的主要内容,如果未能解决你的问题,请参考以下文章

ORM多表查询下

ORM多表操作之一对多查询之对象查询

[Django框架之ORM操作:多表查询,聚合查询分组查询F查询Q查询choices参数]

python 之 Django框架(orm单表查询orm多表查询聚合查询分组查询F查询 Q查询事务Django ORM执行原生SQL)

Django-ORM-多表操作

orm多表查询基于双下划线