zoukankan      html  css  js  c++  java
  • 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("查询成功")

    待续

     

  • 相关阅读:
    python 操作ie 登陆土豆再退出
    python之sqlite3使用详解(转)
    python 获取当前目录下文件(转)
    python中使用time模块计算代码执行效率的精度测试(转)
    pythonhttplib模块使用(转)
    python技巧31[python中使用enum](转)
    python怎样压缩和解压缩ZIP文件(转)
    httplib2python下的http请求终结者(转)
    Python:使用ctypes库调用外部DLL(转)
    整理了下控制ie的代码(转)
  • 原文地址:https://www.cnblogs.com/knighterrant/p/10224222.html
Copyright © 2011-2022 走看看