Django 1.10中文文档-聚合

正文

Django 1.10中文文档: https://github.com/jhao104/django-chinese-doc

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

整篇指南我们都将引用以下模型。这些模型用来记录多个网上书店的库存。

from django.db import models
class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
class Publisher(models.Model):
    name = models.CharField(max_length=300)
    num_awards = models.IntegerField()
class Book(models.Model):
    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)
    registered_users = models.PositiveIntegerField()

速查表

下面是在上面的模型上如何执行常见的聚合查询:

# book 总数.
>>> Book.objects.count()
2452
# publisher=BaloneyPress的book总数.
>>> Book.objects.filter(publisher__name='BaloneyPress').count()
73
# 所有book的平均价格.
>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}
# 所有book的最高价格
>>> from django.db.models import Max
>>> Book.objects.all().aggregate(Max('price'))
{'price__max': Decimal('81.20')}
# 每页均价
>>> from django.db.models import F, FloatField, Sum
>>> Book.objects.all().aggregate(
...    price_per_page=Sum(F('price')/F('pages'), output_field=FloatField()))
{'price_per_page': 0.4470664529184653}
# 下面的所有查询都涉及到遍历 Book<->Publisher
# foreign key relationship backwards.
# 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
<QuerySet [<Publisher: BaloneyPress>, <Publisher: SalamiPress>, ...]>
>>> pubs[0].num_books
73
# The top 5 publishers, in order by number of books.
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
>>> pubs[0].num_books
1323

QuerySet 聚合

Django提供了两种生成聚合的方法。第一种方法是从整个 QuerySet 生成统计值。 比如,你想要计算所有在售书的平均价钱。Django的查询语法提供了一种方式描述所有图书的集合。:

>>> Book.objects.all()

我们需要在 QuerySet 对象上计算出汇总的值。这可以通过在 QuerySet 后面添加 aggregate() 子句来实现:

>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}

其实 all() 在这里可以省略,简化为:

>>> Book.objects.aggregate(Avg('price'))
{'price__avg': 34.35}

aggregate() 子句的参数是想要计算的聚合值,在这个例子中,是 Book 模型中 price 字段的平均值。 查询集参考 有所有的聚合函数。

aggregate() 是 QuerySet 的一个终止子句,意思是说,它返回一个包含键值对的字典。 键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。 如果你想要为聚合值指定一个名称,可以在聚合子句中指定:

>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}

如果你想要计算多个聚合,你可以在 aggregate() 子句作为参数添加。比如, 如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

QuerySet 逐个对象的聚合

生成汇总值的第二种方法,是为 QuerySet 中每一个对象都生

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值