在前一遍文章django models Making queries里面我们提到了django常用的一些检索数据库的内容,

下面我们来看一下更为高级的检索聚合运算

这是我们要用到的模型

class Author(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
friends = models.ManyToManyField('self', blank=True) class Publisher(models.Model):
name = models.CharField(max_length=300)
num_awards = models.IntegerField() class Book(models.Model):
isbn = models.CharField(max_length=9)
name = models.CharField(max_length=300)
pages = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
rating = models.FloatField()
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
pubdate = models.DateField() class Store(models.Model):
name = models.CharField(max_length=300)
books = models.ManyToManyField(Book)

我们直接来看一些高级聚合运算的例子吧

# Total number of books.
>>> Book.objects.count()
2452 # Total number of books with publisher=BaloneyPress
>>> Book.objects.filter(publisher__name='BaloneyPress').count()
73 # Average price across all books.
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35} # Max price across all books.
>>> from django.db.models import Max
>>> Book.objects.all().aggregate(Max('price'))
{'price__max': Decimal('81.20')} # Each publisher, each with a count of books as a "num_books" attribute.
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book'))
>>> pubs
[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]
>>> pubs[0].num_books
73 # The top 5 publishers, in order by number of books.
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
>>> pubs[0].num_books
1323

aggregate(英文原意:a sum total of many heterogenous things taken together,中文释义:合计;集合体;总计)

annotate(英文原意:add explanatory notes to or supply with critical comments,中文释义:注释;给…作注释或评注)

结合上面给出的例子,我们似乎可以这样总结吧

aggregate是对我们我们感兴趣的某一列进行一些操作,返回的是一个字典

annotate是返回的是一个queryset,并且这个queryset有着我们需要的额外字段

继续看一些annotate的例子吧

# Build an annotated queryset
>>> q = Book.objects.annotate(Count('authors'))
# Interrogate the first object in the queryset
>>> q[0]
<Book: The Definitive Guide to Django>
>>> q[0].authors__count
2
# Interrogate the second object in the queryset
>>> q[1]
<Book: Practical Django Projects>
>>> q[1].authors__count
1

接下来我们来进行更高级的操作吧

1:找出每间store的价格范围,很明显,如果你想要范围的结果包含store,你应该用annotate

>>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))

如果你只是想得出所有store的价格范围,你应该用aggregate

 Store.objects.aggregate(min_price=Min('books__price'), max_price=Max('books__price'))

分组查询values()

使用values()可以在查询前后给数据分组

最后我们说几个关于查询顺序的例子

1:annotate和values的顺序

>>> Author.objects.values('name').annotate(average_rating=Avg('book__rating'))
>>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating')

第一行的查询时先对作者分组(相同名字的作者的书会被归在一组),返回每个作者的平均排名

第二行的查询会为每个作者生成一个average_rating,而且只会输出每个author的name和average_rating

2:filter和annotate的顺序

>>> Publisher.objects.annotate(num_books=Count('book')).filter(book__rating__gt=3.0)
>>> Publisher.objects.filter(book__rating__gt=3.0).annotate(num_books=Count('book'))

两个查询都返回了至少出版了一本好书(评分大于3分)的出版商的列表。

但是第一个查询的注解包含其该出版商发行的所有图书的总数;

而第二个查询的注解只包含出版过好书的出版商的所发行的好书(评分大于3分)总数。

在第一个查询中,注解在过滤器之前,所以过滤器对注解没有影响。在第二个查询中,过滤器在注解之前,所以,在计算注解值时,过滤器就限制了参与运算的对象的范围

3:django models Making queries 高级进阶--聚合运算的更多相关文章

  1. 2:django models Making queries

    这是后面要用到的类 class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextFie ...

  2. Django笔记 —— 模型高级进阶

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  3. Django models 操作高级补充

    Django models 操作高级补充 字段参数补充: 外键 约束取消 ..... ORM中原生SQL写法: raw connection extra

  4. Django笔记 —— 模板高级进阶

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  5. Django 1.10中文文档-聚合

    Django 数据库抽象API 描述了使用Django 查询来增删查改单个对象的方法. 然而,有时候你要获取的值需要根据一组对象聚合后才能得到. 这个主题指南描述了如何使用Django的查询来生成和返 ...

  6. django models的点查询/跨表查询/双下划线查询

    django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...

  7. django models 数据库操作

    django models 数据库操作 创建模型 实例代码如下 from django.db import models class School(models.Model): pass class ...

  8. Django models Form model_form 关系及区别

    Django models Form model_form

  9. Django models .all .values .values_list 几种数据查询结果的对比

    Django models .all .values .values_list 几种数据查询结果的对比

随机推荐

  1. 洛谷 P4495 [HAOI2018]奇怪的背包 解题报告

    P4495 [HAOI2018]奇怪的背包 题目描述 小\(C\)非常擅长背包问题,他有一个奇怪的背包,这个背包有一个参数\(P\),当他 向这个背包内放入若干个物品后,背包的重量是物品总体积对\(P ...

  2. Poco::URI

    #include<iostream> #include<typeinfo> #include<Poco/Path.h> #include <Poco/Dire ...

  3. 2017-7-18-每日博客-关于Linux下的history的常用命令.doc

    History history命令可以用来显示曾执行过的命令.执行过的命令默认存储在HOME目录中的.bash_history文件中,可以通过查看该文件来获取执行命令的历史记录.需要注意的是.bash ...

  4. ubuntu14.04安装GTX 1080 ti遇到黑屏问题

    实验室给我配置了一个1080ti的卡,那个激动,windows下1000+的FPS,跑分40W,无敌,言归正传,ubuntu14.04下配nvidia 1080的驱动还是出现了很多问题,差点就要重装系 ...

  5. ACE线程管理机制-线程的创建与管理

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581369.html 有过在不同的操作系统下用c++进行过多线程编程的朋友对那些线程处理 ...

  6. Codeforces Round #342 (Div. 2) C

    C. K-special Tables time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. ACM1811拓扑排序和并查集

    /* ACM1811 可以利用拓扑排序和并查集解决,主要方式是利用并查集在输入数据的时候将所有相等的点合并 然后将处理完的数据统一按照一个符号方向连接成有向线段,利用的是邻接矩阵:接下来把每条边都进行 ...

  8. DEBUG宏

    4.8.6.运算中的临时匿名变量4.8.6.1.C语言和汇编的区别(汇编完全对应机器操作,C对应逻辑操作)(1)C语言叫高级语言,汇编语言叫低级语言.(2)低级语言的意思是汇编语言和机器操作相对应,汇 ...

  9. LightOJ 1093 - Ghajini 线段树

    http://www.lightoj.com/volume_showproblem.php?problem=1093 题意:给定序列,问长度为d的区间最大值和最小值得差最大是多少. 思路:可以使用线段 ...

  10. 2015/8/26 Python基础(1):基本规则及赋值

    Python有如下的基本规则: #后表示注释 \n是行分隔符 \是继续上一行,将过长语句分开 :分号将两个语句连接在一行中 :冒号将代码头和体分开 代码块用缩进块的方式体现 不同缩进深度分隔不同的代码 ...