您的位置:首页 > 编程语言 > Go语言

Django2.0-db(7)-查询操作-聚合函数

2018-11-10 17:25 309 查看

笔记在知了课堂-Django开发的基础上更改

反向查询和反向引用

  • 反向查询: 将模型名字小写化。 比如
    article_in
    。可以通过
    related_query_name
    来指定名字。
  • 反向引用: 将模型名字小写化,加上
    _set
    。比如
    article_set
    ,可以通过
    related_name
    来指定自己的方式。

聚合函数

  • 如果你用原生
    SQL
    ,则可以使用聚合函数来提取数据。比如提取某个商品销售的数量,那么可以使用
    Count
    ,如果想要知道商品销售的平均价格,那么可以使用
    Avg
  • 聚合函数不能单独执行,需要放在一些可以执行聚合函数的方法下面中去执行。比如
    aggregate
    方法来实现的。
  • 聚合函数执行完毕之后,
    Django
    默认给聚合函数的值取个名字。命名规则是
    filed名+__+聚合函数名
  • 在讲解这些聚合函数的用法的时候,都是基于以下的模型对象来实现的。
from django.db import models

class Author(models.Model):
"""作者模型"""
name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField()

class Meta:
db_table = 'author'

class Publisher(models.Model):
"""出版社模型"""
name = models.CharField(max_length=300)

class Meta:
db_table = 'publisher'

class Book(models.Model):
"""图书模型"""
name  = models.CharField(max_length=300)
pages = models.IntegerField()
price = models.FloatField()
rating = models.FloatField()
author = models.ForeignKey(Author,on_delete=models.CASCADE)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)

class Me ta:
db_table = 'book'

class BookOrder(models.Model):
"""图书订单模型"""
book = models.ForeignKey("Book",on_delete=models.CASCADE)
price = models.FloatField()

class Meta:
db_table = 'book_order'

Avg

求平均值。比如想要获取所有图书的价格平均值。那么可以使用以下代码实现。

from django.db.models import Avg
result = Book.objects.aggregate(Avg('price'))
print(result)

以上的打印结果是:

{"price__avg":23.0}

其中

price__avg
的结构是根据
field__聚合函数名
规则构成的。如果想要修改默认的名字,那么可以将
Avg
赋值给一个关键字参数。示例代码如下:

from django.db.models import Avg
result = Book.objects.aggregate(my_avg=Avg('price'))
print(result)

那么以上的结果打印为:

{"my_avg":23}

Count

获取指定的对象的个数。示例代码如下:

from django.db.models import Count
result = Book.objects.aggregate(book_num=Count('id'))

以上的

result
将返回
Book
表中总共有多少本图书。
Count
类中,还有另外一个参数叫做
distinct
,默认是等于
False
,如果是等于
True
,那么将去掉那些重复的值。比如要获取作者表中所有的不重复的邮箱总共有多少个,那么可以通过以下代码来实现:

from djang.db.models import Count
result = Author.objects.aggregate(count=Count('email',distinct=True))

Max和Min

获取指定对象的最大值和最小值。比如想要获取

Author
表中,最大的年龄和最小的年龄分别是多少。那么可以通过以下代码来实现:

from django.db.models import Max,Min
result = Author.objects.aggregate(Max('age'),Min('age'))

如果最大的年龄是88,最小的年龄是18。那么以上的result将为:

{"age__max":88,"age__min":18}

Sum

求指定对象的总和。比如要求图书的销售总额。那么可以使用以下代码实现:

from djang.db.models import Sum
result = Book.objects.annotate(total=Sum("bookstore__price")).values("name","total")

以上的代码

annotate
的意思是给
Book
表在查询的时候添加一个字段叫做
total
,这个字段的数据来源是从
BookStore
模型的
price
的总和而来。
values
方法是只提取
name
total
两个字段的值。

更多的聚合函数请参考官方文档:https://docs.djangoproject.com/en/2.0/ref/models/querysets/#aggregation-functions

aggregate和annotate的区别

  1. aggregate
    :返回使用聚合函数后的字段和值。返回一个dict

  2. annotate
    :**返回一个
    QuerySet。
    **在原来模型字段的基础之上添加一个使用了聚合函数的字段,并且在使用聚合函数的时候,会使用当前这个模型的主键进行分组(group by)。
    比如以上
    Sum
    的例子,如果使用的是
    annotate
    ,那么将在每条图书的数据上都添加一个字段叫做
    total
    (这个字段看你自己设不设置,不设置就使用默认的
    Field__聚合方式名
    ),计算这本书的销售总额。
    而如果使用的是
    aggregate
    ,那么将求所有图书的销售总额。

  3. 都可以在任何的

    QuerySet
    对象调用

    比如要获取2018年度的销售总额,可以先过滤年份,再求聚合函数

    BookOrder.object.filter(create_time__year=2018).aggregate(total=Sun('price'))
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: