Django ORM 聚合查询和分组查询实现详解


Posted in Python onAugust 09, 2019

models.py:

from django.db import models 
# 出版社
class Publisher(models.Model):
  id = models.AutoField(primary_key=True)
  name = models.CharField(max_length=64, null=False, unique=True)
 
  def __str__(self):
    return "<Publisher object: {}>".format(self.name) 
 
# 书籍
class Book(models.Model):
  id = models.AutoField(primary_key=True)
  title = models.CharField(max_length=64, null=False, unique=True)
  price = models.DecimalField(max_digits=5, decimal_places=2, default=00.00) # 最长位数为 5,小数位数为 2,默认值为 00.00
  publisher = models.ForeignKey(to="Publisher", null=True) # 把 null 设置为 True
 
  def __str__(self):
    return "<Book object: {}>".format(self.title)
 
# 作者
class Author(models.Model):
  id = models.AutoField(primary_key=True)
  name = models.CharField(max_length=16, null=False, unique=True)
  book = models.ManyToManyField(to="Book") # 多对多关联 Book 表,ORM 会自动生成第 3 张表
 
  def __str__(self):
    return "<Author object: {}>".format(self.name)

book 表:

Django ORM 聚合查询和分组查询实现详解

修改 price

Django ORM 聚合查询和分组查询实现详解

聚合查询:

aggregate():返回一个包含一些键值对的字典。

键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。

orm.py:

import os 
if __name__ == '__main__':
  # 加载 Django 项目的配置信息
  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
  # 导入 Django,并启动 Django 项目
  import django
  django.setup() 
  from app01 import models 
  # 聚合查询需要导入的函数
  from django.db.models import Avg, Sum, Max, Min, Count 
  # 计算所有书籍 price 的平均值
  avg_ret = models.Book.objects.all().aggregate(Avg("price"))
  print(avg_ret) 
  # 计算所有书籍 price 的总和
  sum_ret = models.Book.objects.all().aggregate(Sum("price"))
  print(sum_ret) 
  # 计算所有书籍 price 的最大值
  max_ret = models.Book.objects.all().aggregate(Max("price"))
  print(max_ret) 
  # 计算所有书籍 price 的最小值
  min_ret = models.Book.objects.all().aggregate(Min("price"))
  print(min_ret) 
  # 计算所有书籍 price 的个数
  count_ret = models.Book.objects.all().aggregate(Count("price"))
  print(count_ret)

运行结果:

Django ORM 聚合查询和分组查询实现详解

生成的是字典类型

分组:

orm.py:

import os 
if __name__ == '__main__':
  # 加载 Django 项目的配置信息
  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
  # 导入 Django,并启动 Django 项目
  import django
  django.setup() 
  from app01 import models 
  from django.db.models import Count 
  # 查询每一本书的作者个数
  ret = models.Book.objects.all().annotate(author_num=Count("author")) # 返回的是 book 对象,annotate(author_num) 相当于让 book 对象多了一个 author_num 字段
  print(ret)   
  for book in ret:
    print("书名:{},作者数:{}".format(book.title, book.author_num))

运行结果:

Django ORM 聚合查询和分组查询实现详解

这里的 book.annotate(author_num) 相当于让 book 对象多了一个 author_num 字段,但并不是在数据库中多了一个字段

orm.py:

import os 
if __name__ == '__main__':
  # 加载 Django 项目的配置信息
  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
  # 导入 Django,并启动 Django 项目
  import django
  django.setup() 
  from app01 import models
  from django.db.models import Count 
  # 查询作者数大于 1 的书
  ret = models.Book.objects.all().annotate(author_num=Count("author")).filter(author_num__gt=1)
  print(ret)

运行结果:

Django ORM 聚合查询和分组查询实现详解

orm.py:

import os 
if __name__ == '__main__':
  # 加载 Django 项目的配置信息
  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
  # 导入 Django,并启动 Django 项目
  import django
  django.setup() 
  from app01 import models 
  from django.db.models import Sum 
  # 查询各个作者出的书的总价格
  ret = models.Author.objects.all().annotate(price_sum=Sum("book__price")) # 获取所有 author 表数据并添加 price_sum 字段 
  for i in ret:
    print(i, i.name, i.price_sum) # 打印所有 author 对象、 author 的 name 字段、price_sum 字段 的数据
  # 打印 author 表的所有 id、name、price_sum 字段数据
  print(ret.values_list("id", "name", "price_sum"))

运行结果:

Django ORM 聚合查询和分组查询实现详解

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

Python 相关文章推荐
Django集成百度富文本编辑器uEditor攻略
Jul 04 Python
使用Python3编写抓取网页和只抓网页图片的脚本
Aug 20 Python
python编程开发之类型转换convert实例分析
Nov 13 Python
python检查URL是否正常访问的小技巧
Feb 25 Python
Python对列表去重的多种方法(四种方法)
Dec 05 Python
Python实现PS图像调整之对比度调整功能示例
Jan 26 Python
浅谈Django的缓存机制
Aug 23 Python
python利用thrift服务读取hbase数据的方法
Dec 27 Python
python 3.6.7实现端口扫描器
Sep 04 Python
解决django FileFIELD的编码问题
Mar 30 Python
详解python模块pychartdir安装及导入问题
Oct 22 Python
浅谈Python项目的服务器部署
Apr 25 Python
解决Django后台ManyToManyField显示成Object的问题
Aug 09 #Python
详解Python中的正斜杠与反斜杠
Aug 09 #Python
图文详解Django使用Pycharm连接MySQL数据库
Aug 09 #Python
Django ORM多对多查询方法(自定义第三张表&amp;ManyToManyField)
Aug 09 #Python
Django使用Jinja2模板引擎的示例代码
Aug 09 #Python
在Django admin中编辑ManyToManyField的实现方法
Aug 09 #Python
Django使用 Bootstrap 样式修改书籍列表过程解析
Aug 09 #Python
You might like
一些常用的php简单命令代码集锦
2007/09/24 PHP
php 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
Zend Framework教程之模型Model用法简单实例
2016/03/04 PHP
浅谈PHP中new self()和new static()的区别
2017/08/11 PHP
jquery div 居中技巧应用介绍
2012/11/24 Javascript
原生js拖拽(第一课 未兼容)拖拽思路
2013/03/29 Javascript
利用毫秒减值计算时长的js代码
2013/09/22 Javascript
Nodejs实现多人同时在线移动鼠标的小游戏分享
2014/12/06 NodeJs
jquery加载图片时以淡入方式显示的方法
2015/01/14 Javascript
深入理解JavaScript系列(50):Function模式(下篇)
2015/03/04 Javascript
javascript实现的字符串与十六进制表示字符串相互转换方法
2015/07/17 Javascript
js实现不提交表单获取单选按钮值的方法
2015/08/21 Javascript
详解JS中Array对象扩展与String对象扩展
2016/01/07 Javascript
jQuery实现的网页换肤效果示例
2016/09/20 Javascript
最原始的jQuery注册验证方式
2016/10/11 Javascript
微信小程序 教程之列表渲染
2016/10/18 Javascript
JavaScript实现全选取消效果
2017/12/14 Javascript
jQuery+datatables插件实现ajax加载数据与增删改查功能示例
2018/04/17 jQuery
微信小程序实现星级评分和展示
2018/07/05 Javascript
一次微信小程序内地图的使用实战记录
2019/09/09 Javascript
通过实例解析JavaScript for in及for of区别
2020/06/15 Javascript
OpenLayers实现图层切换控件
2020/09/25 Javascript
vue中activated的用法
2021/01/03 Vue.js
解决谷歌搜索技术文章时打不开网页问题的python脚本
2013/02/10 Python
Python程序设计入门(2)变量类型简介
2014/06/16 Python
Python实现将绝对URL替换成相对URL的方法
2015/06/28 Python
python linecache 处理固定格式文本数据的方法
2019/01/08 Python
python3实现指定目录下文件sha256及文件大小统计
2019/02/25 Python
numpy.where() 用法详解
2019/05/27 Python
python内置模块collections知识点总结
2019/12/19 Python
员工年终演讲稿
2014/01/03 职场文书
服务承诺书格式
2014/05/21 职场文书
工作能力自我评价2015
2015/03/05 职场文书
2015年七一建党节慰问信
2015/03/23 职场文书
2015年会计人员工作总结
2015/05/22 职场文书
Python 可迭代对象 iterable的具体使用
2021/08/07 Python