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

yipeiwu_com6年前Python基础

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 表:

修改 price

聚合查询:

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)

运行结果:

生成的是字典类型

分组:

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))

运行结果:

这里的 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)

运行结果:

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"))

运行结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

Python随机生成均匀分布在单位圆内的点代码示例

Python随机生成均匀分布在单位圆内的点代码示例

Python有一随机函数可以产生[0,1)区间内的随机数,但是如果我们想生成随机分布在单位圆上的,那么我们可以首先生成随机分布在单位圆边上的点,然后随机调整每个点距离原点的距离,但是我们...

用python写的一个wordpress的采集程序

用python写的一个wordpress的采集程序

在学习python的过程中,经过不断的尝试及努力,终于完成了第一个像样的python程序,虽然还有很多需要优化的地方,但是目前基本上实现了我所要求的功能,先贴一下程序代码: 具体代码如...

python利用hook技术破解https的实例代码

相对于http协议,http是的特点就是他的安全性,http协议的通信内容用普通的嗅探器可以捕捉到,但是https协议的内容嗅探到的是加密后的内容,对我们的利用价值不是很高,所以一些大的...

在Python的Django框架的视图中使用Session的方法

SessionMiddleware 激活后,每个传给视图(view)函数的第一个参数``HttpRequest`` 对象都有一个 session 属性,这是一个字典型的对象。 你可以象用...

Python中字典的基础知识归纳小结

定义一个字典 >>> d = {"server":"mpilgrim", "database":"master"} 1 >>> d {'serve...