django的聚合函数和aggregate、annotate方法使用详解

支持聚合函数的方法:

提到聚合函数,首先我们要知道的就是这些聚合函数是不能在django中单独使用的,要想在django中使用这些聚合函数,就必须把这些聚合函数放到支持他们的方法内去执行。支持聚合函数的方法有两种,分别是aggregate和annotate,这两种方法执行的原生SQL以及结果都有很大的区别,下面我们以实例操作的方式一一介绍:

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

  class Book(models.Model):
    """图书模型"""
    name = models.CharField(max_length=100)
    author = models.ForeignKey('Author',on_delete=models.CASCADE)
    price = models.FloatField()

  class BookOrder(models.Model):
    """图书订单模型"""
    book = models.ForeignKey('Book',on_delete=models.CASCADE)
    sailprice = models.FloatField()
    create_time = models.DateTimeField(auto_now_add=True)

1、aggregate:这个方法时一个QuerySet对象的API,在执行聚合函数的时候,是对QuerySet整个对象的某个属性汇总,在汇总时不会使用该模型的主键进行group by进行分组,得到的是一个结果字典。同时,该方法支持聚合关联表(如使用ForeignKey)中的字段,在聚合连表中字段时,传递该字段的方式与查询连表时传递字段的方式相同,会使用到"__"。示例代码如下:

  from django.db.models import Avg
  from django.db import connection

1、对当前表中数据进行聚合:

  result = Author.objects.aggregate(avg_age=Avg('age'))
  print(connection.queries)	  # 打印执行时所有的查询语句

2、对连表中数据进行聚合:

  result = Book.objects.aggregate(sum=Sum('bookorder__price'))

2、annotate:这个方法不但可以执行聚合函数,也可以传递F、Q对象为当前QuerySet生成一个新的属性。

这个方法一般聚合的是连表中的字段,会为当前QuerySet中的每个对象生成一个独立的摘要,为查询的模型增加一个新的属性,这个属性的值就是使用聚合函数所得到的值,在使用这个聚合函数的时候annotate会使用这个模型的主键进行group by进行分组(注意这里只有在使用聚合函数生成新字段的时候会进行group by,在使用F、Q表达式增添新字段时,并不会使用group by),然后在连表中根据分组的结果进行聚合,这一点正符合为QuerySet中每个对象增加一个独立摘要的事实。

使用这个方法执行聚合函数,得到的结果是一个QuerySet对象,结果依然能够调用filter()、order_by()甚至annotate()进行再次聚合,现在我想提取每一本书的平均销售的价格(注意销售价格在BookOrder表中):

  from django.db.models import Avg
  from django.db import connection 

  books = Book.objects.annotate(avg=Avg('bookorder__sailprice'))
  for book in books:
  print('%s/%s'%(book.name,book.avg))  	# 注意这里的avg属性就是annotate执行聚合函数得到的
  print(connection.queries)

聚合函数:

在Django中,聚合函数都是在django.db.models模块下的,具体的聚合函数有Avg、Count、Max、Min、Sum,现在我们一一介绍这些函数的作用:

1、Avg:计算平均值,使用于与数值相关的字段,如果使用aggregate方法来执行这个函数,那么会得到一个字典,默认情况下,字典的键为field__avg,值为执行这个聚合函数所得到的值,示例代码如下:

  # 计算所有作者的平均年龄
  result = Author.objects.aggregate(Avg('age'))
  print(result)	# 结果为:{"age__avg": 23.8}

  # 如果想要使用自定义的键,那么可以把aggregate中的未知参数变为关键字参数,该关键字就是得到的键,示例代码如下:
  result = Author.objects.aggregate(avgAge=Avg('age'))
  print(result)	# 结果为:{"avgAge": 23.8} 

  # 如果使用annotate方法执行这个函数,那么得到的结果就是一个QuerySet对象,只不过这个对象中的每一个都会添加一个属性,这个属性的名称其实和上面的键一样,可以使用默认也可以自定义,使用方法与在aggregate中键名的定义一样,这里就不再赘述:
  books = Book.objects.annotate(avg=Avg('bookorder__sailprice'))
  for book in books:
    print('%s/%s'%(book.name,book.avg))	# 注意这里的avg属性就是annotate执行聚合函数得到的
  print(connection.queries)

2、Count:计算数量,基本用法与Avg相同,在使用这个聚合函数的时候可以传递一个distinct参数用来去重:

  # 计算总共有多少个订单
  result = BookOrder.objects.aggregate(total=Count('id',distanct=True))
  print(result)	# 结果为:{"total": 18}

  # 计算每本书的订单量
  books = Book.objects.annotate(total=Count('bookorder__id'))
  for book in books:
  print('%s/%s'%(book.name,book.total))

3、Max和Min:计算某个字段的最大值和最小值,用法与Avg一样

4、Sum:计算总和,用法与Avg一样

注:总结一下,其实可以简单的理解使用aggregate时,是对QuerySet整个对象的某个属性汇总聚合,不会使用分组。而使用annotate方法时,是为QuerySet中的每个对象生成一个独立的摘要,一定会使用分组,然后再聚合

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 在Django的模型和公用函数中使用惰性翻译对象

    在模型和公用函数中,使用ugettext_lazy()和ungettext_lazy()来标记字符串是很普遍的操作. 当你在你的代码中其它地方使用这些对象时,你应当确定你不会意外地转换它们成一个字符串,因为它们应被尽量晚地转换(以便正确的地域生效) 这需要使用几个帮助函数. 拼接字符串: string_concat() 标准Python字符串拼接(''.join([...]) ) 将不会工作在包括惰性翻译对象的列表上. 作为替代,你可以使用django.utils.translation.str

  • Django基础三之视图函数的使用方法

    一 Django的视图函数view 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. 无论视图本身包含什么逻辑,都要返回响应.代码写在哪里也无所谓,只要它在你当前项目目录下面.除此之外没有更多的要求了--可以说"没有什么神奇的地方".为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为view

  • 用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化

    实例的背景说明 假定一个个人信息系统,需要记录系统中各个人的故乡.居住地.以及到过的城市.数据库设计如下: Models.py 内容如下: from django.db import models class Province(models.Model): name = models.CharField(max_length=10) def __unicode__(self): return self.name class City(models.Model): name = models.Ch

  • 浅谈django的render函数的参数问题

    hello.html 文件代码如下: HelloWorld/templates/hello.html 文件代码: <h1>{{ hello }}</h1> HelloWorld/HelloWorld/view.py 文件代码: # -*- coding: utf-8 -*- #from django.http import HttpResponse from django.shortcuts import render def hello(request): context = {

  • Django中URL视图函数的一些高级概念介绍

    说到关于请求方法的分支,让我们来看一下可以用什么好的方法来实现它. 考虑这个 URLconf/view 设计: # urls.py from django.conf.urls.defaults import * from mysite import views urlpatterns = patterns('', # ... (r'^somepage/$', views.some_page), # ... ) # views.py from django.http import Http404,

  • Django框架中render_to_response()函数的使用方法

    通常的情况是,我们一般会载入一个模板文件,然后用 Context渲染它,最后返回这个处理好的HttpResponse对象给用户. 我们已经优化了方案,使用 get_template() 方法代替繁杂的用代码来处理模板及其路径的工作. 但这仍然需要一定量的时间来敲出这些简化的代码. 这是一个普遍存在的重复苦力劳动.Django为此提供了一个捷径,让你一次性地载入某个模板文件,渲染它,然后将此作为 HttpResponse返回. 该捷径就是位于 django.shortcuts 模块中名为 rend

  • 聚合函数和group by的关系详解

    目录 前言 聚合函数介绍 group by介绍 解释聚合函数和group by的关系 使用group by和聚合函数需要注意的地方 总结 前言 world:世界表格continent:大洲名称name:国家名称population:人口数量 聚合函数介绍 sum() 求和函数 avg() 求平均值函数 max() 求最大值函数 min() 求最小值函数 count() 求行数函数 group by介绍 group up + 字段名:规定哪个字段分组聚合在单独使用使用时,作用为分组去重 结果与di

  • django的聚合函数和aggregate、annotate方法使用详解

    支持聚合函数的方法: 提到聚合函数,首先我们要知道的就是这些聚合函数是不能在django中单独使用的,要想在django中使用这些聚合函数,就必须把这些聚合函数放到支持他们的方法内去执行.支持聚合函数的方法有两种,分别是aggregate和annotate,这两种方法执行的原生SQL以及结果都有很大的区别,下面我们以实例操作的方式一一介绍: # 示例模型: class Author(models.Model): """作者模型""" name =

  • Python Django给admin添加Action的方法实例详解

    在使用Django自带的admin后台的时候,他提供了一些默认的指令可以对数据进行操作, 比如批量删除,修改等 同样的我们也可以添加自己的指令. 创建一个Django项目 $ django-admin startproject DjangoActions $ cd DjangoActions $ python3 manage.py startapp mysite添加model 打开mysite下的models.py from django.db import models class Artic

  • MongoDB中aggregate()方法实例详解

    目录 前言 1,了解aggergate()方法 2,实现聚合表达式运算符 总结 前言 MongoDB的一个很大的好处是能够使用MapReduce来吧数据库查询的结果简化成一个与原来的集合完全不同的结构.MapReduce把一个数据库查询的值映射为一个完全不同的形式,然后简化结果,使它们的可用性更好. MongoDB有一个MapReduce框架,它也允许你使用聚合来简化吧一个MapReduce操作传输到另一个MapReduce操作的一系列过程.有了MapReduce和聚合,可以用数据生成一些不平凡

  • JavaScript函数之call、apply以及bind方法案例详解

    总结 1.相同点 都能够改变目标函数执行时内部 this 的指向 方法的第一个参数用于指定函数执行时内部的 this 值 支持向目标函数传递任意个参数 若不向方法的第一个参数传值或者传递 undefined.null,则在 JavaScript 正常模式下,目标函数内部的 this 指向 window 对象,严格模式下,分别指向 undefined.null. 2.区别 apply() 方法可接收两个参数,而 call() 和 bind() 方法则可接收多个参数. apply() 方法向目标函数

  • Django零基础入门之路由path和re_path详解

    目录 urls.py文件中的path和re_path 1.path的基本规则: 2.默认支持的转换器有: 3.re_path正则匹配: Django中实战使用path和re_path 1.urls.py文件: 2.views.py视图函数文件: 3.效果: 假设现在有个需求:   需要通过URL进行参数传递,我们该怎么做呢?     其中有个方法就是本文要讲的内容--path和进阶版的re_path. urls.py文件中的path和re_path 1.path的基本规则: path('test

  • apache zookeeper使用方法实例详解

    本文涉及了Apache Zookeeper使用方法实例详解的相关知识,接下来我们就看看具体内容. 简介 Apache Zookeeper 是由 Apache Hadoop 的 Zookeeper 子项目发展而来,现在已经成为了 Apache 的顶级项目.Zookeeper 为分布式系统提供了高效可靠且易于使用的协同服务,它可以为分布式应用提供相当多的服务,诸如统一命名服务,配置管理,状态同步和组服务等. Zookeeper 接口简单,开发人员不必过多地纠结在分布式系统编程难于处理的同步和一致性问

  • Kotlin 语言中调用 JavaScript 方法实例详解

    Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作.它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java 类.但是,JavaScript 是一种动态类型语言,这意味着它不会在编译期检查类型.你可以通过动态类型在 Kotlin 中自由地与 JavaScript 交流,但是如果你想要 Kotlin 类型系统的全部威力 ,你可以为 JavaScript 库创建 Kotlin 头文件. 内联 J

  • IOS 中KVC的使用方法实例详解

    IOS 中KVC的使用方法实例详解 KVC是Key Value Coding的缩写,意思是键值编码.在iOS中,提供了一种方法通过使用属性的名称(也就是Key)来间接访问对象的属性方法.说的有的拗口,实际上就是通过类定义我们可以看到类的各种属性,那么使用属性的名称我们就能访问到类实例化后的对象的这个属性值. 这个方法可以不通过getter/setter方法来访问对象的属性.因为一个类的成员变量如果没有提供getter/setter的话,外界就失去了对这个变量的访问渠道.而KVC则提供了一种访问的

  • PHP中Closure类的使用方法及详解

    Closure,匿名函数,又称为Anonymous functions,是php5.3的时候引入的.匿名函数就是没有定义名字的函数.这点牢牢记住就能理解匿名函数的定义了. Closure 类(PHP 5 >= 5.3.0)简介 用于代表 匿名函数 的类. 匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象,下面我们来看一下PHP Closure类的使用方法及介绍. PHP Closure类之前在PHP预定义接口中介绍过,但它可不是interface哦,它是一个内部的final类.Clo

随机推荐