zoukankan      html  css  js  c++  java
  • django中的跨表查询梳理

    1.前言

    	最近在写一个小项目,里面主要涉及的就是表与表之间复杂的关系。当真正开发起来的时候,才发现自己对复杂的表关系间的查询有点混乱,趁着这几天的时间,重新梳理了一下。
    

    2.概念

    在开始之前,先明确几个基础概念:
    
    正向查询:关联字段所在的表查询其关联表叫正向查询
    
    反向查询:未写关联字段的表查询其关联表叫反向查询
    
    # 书籍表
    class Book(models.Model):
        name = models.CharField(max_length=32)
        publish = models.ForeignKey(to='Publish')
        def __str__(self):
            return self.t_name
    
    # 出版社表    
    class Publish(models.Model):
        name = models.CharField(max_length=32)
        def __str__(self):
            return self.t_name
        
    # 根据书籍表,查询其出版社,叫正向查询
    
    # 根据出版社,查询书籍,叫反向查询
    

    3.一对多

    • 正向查询(按字段)
    book_obj=Book.objects.filter(pk=1).first() 		# 拿到书籍为1对对象
    
    publish_name = book_obj.publish.name			# 根据字段查询
    
    • 反向查询(按表名)
    # 查询a出版社出版的书籍
    
    book_list = Publish.book_set.all()		# queryset对象
    

    4.多对多

    • 正向查询(按字段)
    author_list = Book.objects.filter(pk=1).first().author.all()
    
    # 多对多的关系,一本书查出来的作者可能是多个,所以一定是一个queryset对象
    
    • 反向查询(按表名)
    Author.objects.filter(pk=1).first().book_set.all()
    
    # 多对多的关系,一作者查出来的书可能是多本,所以一定是一个queryset对象
    
    注意:在ForeignKey()和ManyToManyField()可以设置related_name的值来赋值FOO_set
    class Book(model.Model):
    	publish = ForeignKey(Book, related_name='bookList')
    
    # 查询
    Publish.objects.filter(pk=1).first().bookList.all()
    

    5.基于双下划线的查询

    	django还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止,同样的,正向查询按字段,反向查询按表名小写。
    
    • 一对多
    # 查询a出版社出版的书的名字(name)和数量(num)		正向查询,按字段
    
    Book.objects.filter(publish__name='a出版社').values_list('naem','num')
    
    # 查询a出版社出版的书的名字(name)和数量(num)		反向查询,按字段
    
    Publish.objects.filter(name='a出版社').
    						values_lsit('book__name','book_num')
        
    # 其实本质是一样的,就是sql语句的select from的表不同而已
    
    • 多对多
    # 查询a作者的书的名字(name)和数量(num)		正向查询,按字段
    
    Book.objects.filter(author__name='a').values_list('naem','num')
    
    # 查询a出版社出版的书的名字(name)和数量(num)		反向查询,按字段
    
    Author.objects.filter(name='a').
    						values_lsit('book__name','book_num')
    

    6.分组查询

    	annotate()为调用QuerySet中每一个对象都生成一个独立的统计值,本质就是将关联的表用sql语句中的join成一张表,再按单表查询的方法进行操作。
    

    7.django中的F查询和Q查询

    	在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。而现实的需求中往往会有两个字段的值做比较这样的需求,django给我们提供了这两种查询方法。
    
    • F()
    # 查询评论数大于收藏数的书籍
     from django.db.models import F
        
     Book.objects.filter(commnetNum__lt=F('keepNum'))
    
    # 将每本书的价格提高30
    Book.objects.all().update(price=F("price")+30) 
    
    • Q()
    bookList=Book.objects.filter(Q(author__name="a")|Q(author__name="b"))
    

    8.总结

    	数据的操作,往往是项目中的关键一步,理清楚数据间的关系和查询方法,更有助于程序的开发。
    
  • 相关阅读:
    整数转字符串
    SharePoint介绍性文章
    Disable Sharepoint 2007 show as System Account when system admin login
    通过IP地址获得主机名
    从文本文件读取信息
    数据库连接池问题[转]
    企业类库问题 public key 问题[经过自己测试]
    Google Analytics异步代码创建虚拟浏览量跟踪
    同一主机上WordPress博客更换域名简易八步骤(2)
    关于application/xwwwformurlencoded等字符编码的解释说明
  • 原文地址:https://www.cnblogs.com/oden/p/10771059.html
Copyright © 2011-2022 走看看