zoukankan      html  css  js  c++  java
  • 多表查询, 聚集查询和分组查询

     

     

    有如下模型为例

    class Publisher(models.Model):
        name = models.CharField(max_length=30)
        address = models.CharField(max_length=50) 
        website = models.URLField()
    
    class Author(models.Model):
        name = models.CharField(max_length=30)
    
    class AuthorDetail(models.Model):
        sex = models.BooleanField(max_length=1, choices=((0,''),(1,''),))
        email = models.EmailField()
        birthday = models.DateField()
        author = models.OneToOneField(Author, on_delete=models.CASCADE)
    
    class Book(models.Model):
        title = models.CharField(max_length=100)
        authors = models.ManyToManyField(Author)
        publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
        publication_date = models.DateField()

     

    一. 多表查询
     
    1)查询作者的所有完整信息
    注意authordetail表中没有作者名字,名字在author表中
    AuthorDetail.objects.values('sex','email','address','author__name')
    author是AuthorDetail表中的外键字段,在外键后面加2个下划线跟上Author表中的name属性,就可输出Author表中的名字
     
    如果想单独获得某个作者的姓名,如下
    author_detail = AuthorDetail.objects.filter(email="123@qq.com")
    name1 = author_detail.author.name
     
     
     
    2)查询<<我的祖国>>这本书的作者名字,出版社名字
    书和作者是多对多关系
    Book.objects.filter(title='我的祖国').values('authors__name')
    Book.objects.filter(title='我的祖国').values('publisher__name')
     
    3)查询胡大海写了什么书
    Book.objects.filter(authors__name='胡大海').values('title')
     
    4)查询广东人民出版社出了什么书
    Book.objects.filter(publisher__name='广东人民出版社').values('title')
     
    5)查询广东人民出版社都有哪些作者出过书
    Book.objects.filter(publisher__name='广东人民出版社').values('author__name')
     
     
    多表查询技巧
    1. 两个下划线可生成连接查询,查询关联的字段信息,可用于外键查询主键字段信息,用objects操作
    例如:book = Book.objects.filter(publisher__name='广东人民出版社')
     
    2. _set提供了对象访问相关联表数据的方法,使用外键相关模型的小写名称,下划线和单词set。但是这种方法只能是关键类访问外键类
    我们有模型Publisher和Book,而Book类中我们通过外键关联到了Publisher。
    下面我们定义一个publisher对象表示一个出版社,就可以使用publisher.book_set的方法获取相关联的书籍信息了
    publisher = Publisher.objects.get(name='广东人民出版社')
    publisher.book_set.all().values()
     
    book.authors_set.all() 这种方法会报错
    因为authors不是Book类中的外键,这样操作行不通
     
     
    注意:
    使用filter过滤的时候,不仅仅可以指定本模型上的某个属性要满足什么条件,还可以指定相关联的模型满足什么属性
    比如查找所有书的标题为title1的出版商
    pubs = Publisher.objects.filter(book__title = "title1")    #注意这里用Book类的小写加__title的方式
     
     
     
     
    二. 常见的查询方法
    常见的查询相关的API
    1)get(**kwargs):返回于所有筛选条件相匹配的对象,返回结果只有一个。如果符合条件的对象超过一个,就抛出MultipleObjectsReturn异常,如果没找到符合条件的对象,抛出DoesNotExist异常。
    注意:
    它返回的不是QuerySet对象,而是models的对象,比如pub=Publisher.object.get(id=1)
    type(pub)返回结果为class 'hello.models.Publisher'
     
    2)all(): 查询所有结果
    3)filter(**kwargs):包含与所筛选条件相匹配的对象,结果可有多个
    4)exclude(**kwargs):包含那些与所选条件不匹配的对象,和filter相反
    5)order_by(*fields):对查询结果排序
    6)reverse():对查询结果反向排序
    7)distinct():从返回结果中剔除重复记录
    8)values(*fields):返回一个ValuesQuerySet, 一个特殊的QuerySet子类,运行后得到的是一个可迭代的字典序列
    9)values_list(*fields): 与values()功能一样,只是返回结果是元组序列
    10)count():返回数据库中匹配查询(QuerySet)的对象数量
    11)first(): 返回第一条记录,等价于[:1][0]
    例如Publisher.objects.all().first()
    12) last(): 返回最后一个记录,等价于[::-1][0]
    13) exists() :如果QuerySet包含数据,就返回True,否则返回False
    例如:Publisher.objects.all().exists()
     
     

     

    三.  聚集查询和分组查询 

    先看QuerySet里的两个函数 
    1. annotate(*args,**kwargs):可以为QuerySet中的每个对象添加注解。通过计算查询结果中的每个对象所关联的对象集合,得到总值(也可以是平均值等),用于分组查询
    2. aggregate(*args, **kwargs): 通过对QuerySet进行计算,返回一个聚合值的字典。aggregate()中的每个参数指定一个包含在字典中的返回值。用于聚合查询

     一些聚合函数所在位置:django.db.models,举例如下

    1. Avg: 返回所给字段平均值
    2. Count:根据所给的关联字段返回被关联model的数量
    3. Max: 返回所给字段的最大值
    4. Min:返回所给字段的最小值
    5. Sum:计算所给字段值总和
     
    实例 
    1. 在Book模型中增加一个price属性
    price = models.DecimalField(max_digits=5, decimal_places=2, default=10)
     
    2. 查询广东人民出版社出了多少本书 
    Publisher.objects.filter(name='广东人民出版社').count() #注意count是小写, 是QuerySet提供的一个方法
    如果使用聚合函数,如下
    from django.db.models import *
    Publisher.objects.filter(name='广东人民出版社').aggregate(Count('name'))
     
    可以自定义个别名 
    Publisher.objects.filter(name='广东人民出版社').aggregate(mycount = Count('name'))
     
    3. 查询胡大海出的书的总价格是多少
    Book.objects.filter(authors__name = '胡大海').aggregate(Sum('price'))
     
    4. 查询各作者出书的总价格是多少, 需要进行分组
    Book.objects.values('authors__name').annotate(Sum('price'))
    其中values()可以当做分组条件,annotate()用于分组查询
     
    5. 查询各出版社最便宜的书价 
    Book.objects.values('publisher__name').annotate(Min('price'))
    on_delete=models.CASCADE
  • 相关阅读:
    HDU 1525
    kmp模板
    hdu 4616 Game(树形DP)
    hdu 4619 Warm up 2(并查集活用)
    hdu 4614 Vases and Flowers(线段树加二分查找)
    Codeforces 400D Dima and Bacteria(并查集最短路)
    poj 2823 Sliding Window (单调队列)
    hdu 2196 Computer(树形dp)
    hdu 4604 Deque
    最短路径
  • 原文地址:https://www.cnblogs.com/regit/p/9243452.html
Copyright © 2011-2022 走看看