Django 聚合查询

文章目录

  • 一、聚合查询
  • 二、使用步骤
    • 1.准备工作
    • 2.具体使用
    • 3.分组查询(annotate)
      • 1.定义
      • 2.使用
      • 3.具体案例
    • 4.F() 查询
      • 1.定义
      • 2.使用
    • 5.Q() 查询
      • 1.定义
      • 2.查询


一、聚合查询

使用聚合查询前要先从 django.db.models 引入 Avg、Max、Min、Count、Sum(首字母大写)
聚合查询返回值的数据类型是字典

聚合查询使用aggregate()对查询集执行聚合操作,它允许我们使用数据库提供的聚合函数(如 COUNT(), AVG(), SUM(), MAX(), MIN() 等)来对查询集中的数据进行汇总计算,aggregate() 方法返回一个字典,字典的键是你指定的聚合函数别名,值是聚合计算的结果

queryset.aggregate(聚合函数)# 别名使用
queryset.aggregate(别名 = 聚合函数名("属性名称"))
# 例:
result = Book.objects.aggregate(average_price=Avg('price'), total_books=Count('id'))
# 结果示例: {'average_price': 100.25, 'total_books': 150}

二、使用步骤

1.准备工作

还是之前那个fa的项目目录,在views.py内引入

# 导入聚合函数
from django.db.models import Avg,Max,Min,Count,Sum

在models.py里面,定义一个Book模型

class Book(models.Model):title = models.CharField(max_length=255)  # 书名author = models.CharField(max_length=255)  # 作者price = models.DecimalField(max_digits=10, decimal_places=2)  # 价格rating = models.FloatField()  # 评分published_date = models.DateField()  # 出版日期pages = models.IntegerField()  # 页数def __str__(self):return self.title

在数据库生成book表,执行下列命令

python manage.py makemigrations
python manage.py migrate

这个时候我们就有一张book的表了,我们自己手动塞入一些数据(这里就不做新增了),然后在下一步实现聚合函数的使用
随意添加的数据
在这里插入图片描述

2.具体使用

定义一个方法去使用聚合函数,我们在views.py里面添加一个方法

def getBookSomeInfo(request):# 计算书的平均价格average_price = models.Book.objects.aggregate(avg_price = Avg('price'))# 如果不加别名结果为: {'price__avg': 100.25}# 获取书的最高价格max_price = models.Book.objects.aggregate(Max('price'))# 获取书的最低价格min_price = models.Book.objects.aggregate(min_price = Min('price'))# 统计书的总数量# book_count = models.Book.objects.aggregate(Count('id'))book_count = models.Book.objects.aggregate(book_count = Count('id'))# 其实也可以使用 len(models.Book.objects.all()) / models.Book.objects.count()# 计算所有书的总价格total_price = models.Book.objects.aggregate(total_price = Sum('price'))return HttpResponse(f"平均价格: {average_price}, 最高价格: {max_price}, 最低价格: {min_price}, 总数量: {book_count}, 总价格: {total_price}")

在路由urls.py里面添加

    path('getBookSomeInfo', views.getBookSomeInfo, name='getBookSomeInfo'),

访问链接http://127.0.0.1:8082/article/getBookSomeInfo
在这里插入图片描述

3.分组查询(annotate)

1.定义

annotate() 是 Django ORM 提供的一个方法,用于在查询集中为每个对象添加计算值。与 aggregate() 方法不同,annotate() 是逐个对象进行计算,而 aggregate() 是对整个查询集进行计算,并返回一个汇总结果

2.使用

使用前要先从 django.db.models 引入聚合函数,annotate() 方法接受一个或多个聚合函数作为参数,这些聚合函数会被应用到查询集中,并将结果作为额外字段添加到每个对象上

queryset.annotate(聚合函数)

3.具体案例

我们先修改一下刚刚定义的Book模型,同时增加一个作者User模型

class User(models.Model):name = models.CharField(max_length=255)  # 作者名称def __str__(self):return self.nameclass Book(models.Model):title = models.CharField(max_length=255)  # 书名# author = models.CharField(max_length=255)  # 作者user = models.ForeignKey(User, related_name='books', null=True, on_delete=models.CASCADE)  # 作者price = models.DecimalField(max_digits=10, decimal_places=2)  # 价格rating = models.FloatField()  # 评分published_date = models.DateField()  # 出版日期pages = models.IntegerField()  # 页数def __str__(self):return self.title

执行命令生成数据表,user表和book表都先手动写入数据,不通过程序写入数据
views.py增加方法

def getBookFormUser(request):# 计算每个作者的书籍数量# 这里的 'books' 是 models.User 类中定义的外键名称,如果外键名称不是 'books' 则需要修改users_with_book_count = models.User.objects.annotate(book_count = Count('books'))users_with_book_count_str = ''# 输出每个作者的书籍数量for user in users_with_book_count:users_with_book_count_str += f"{user.name} has {user.book_count} books.\n"# 计算每个作者的书籍平均价格# books__price 代表 books 外键的 price 字段users_with_avg_price = models.User.objects.annotate(avg_price = Avg('books__price'))users_with_avg_price_str = ''# 输出每个作者的书籍平均价格for user in users_with_avg_price:users_with_avg_price_str += f"{user.name} has an average book price of {user.avg_price}.\n"# 计算每个作者的书籍总价格和最高评分users_with_totals = models.User.objects.annotate(total_price = Sum('books__price'), highest_rating = Max('books__rating'))users_with_totals_str = ''# 输出每个作者的书籍总价格和最高评分for user in users_with_totals:users_with_totals_str += f"{user.name} has a total book price of {user.total_price} and the highest rating is {user.highest_rating}.\n"# 返回带有换行符的 HTML 响应,确保编码为UTF-8return HttpResponse(f"每个作者的书籍数量: <br>{users_with_book_count_str}<br>"f"每个作者的书籍平均价格: <br>{users_with_avg_price_str}<br>"f"每个作者的书籍总价格和最高评分: <br>{users_with_totals_str}",content_type="text/html; charset=utf-8")

增加路由

path('getBookFormUser', views.getBookFormUser, name='getBookFormUser'),

访问链接http://127.0.0.1:8000/article/getBookFormUser
在这里插入图片描述

4.F() 查询

1.定义

F() 表达式用于在数据库中直接引用字段的值,而不是将值从数据库取出后再进行计算。它允许你在数据库层面进行原子性的计算操作,从而避免出现竞争条件或数据不同步的问题,常用于以下场景:

对字段值进行加减、乘除等数学运算。
比较同一个模型中不同字段的值。
更新字段时直接使用该字段的当前值。

2.使用

要使用 F() 表达式,你需要从 django.db.models 中导入 F 类

from django.db.models import F
  1. 字段值的更新(如:增加浏览数)
  2. 先更新一下Book模型
class Book(models.Model):title = models.CharField(max_length=255)  # 书名# author = models.CharField(max_length=255)  # 作者user = models.ForeignKey(User, related_name='books', null=True, on_delete=models.CASCADE)  # 作者price = models.DecimalField(max_digits=10, decimal_places=2)  # 价格rating = models.FloatField()  # 评分published_date = models.DateField()  # 出版日期pages = models.IntegerField()  # 页数views = models.IntegerField(default=0)  # 浏览量def __str__(self):return self.title
  1. 定义方法和路由
def addViews(request):# 增加阅读量article_id = 1models.Book.objects.filter(id=article_id).update(views=F('views') + 1)return HttpResponse('Views added successfully')path('addViews', views.addViews, name='addViews'),
  1. 访问链接http://127.0.0.1:8000/article/addViews
    在这里插入图片描述
  2. 一些其他场景
    定义方法和路由
def someOtherInfo(request):# 比较同一个模型的两个字段的值# 获取 price 大于 discount_price 的商品,这个查询会返回所有 price 大于 discount_price 的 Product 实例# 注意:F() 函数用于引用其他字段的值,不能用于直接比较两个字段的值,price和views都是字段名book_gt_discount = models.Book.objects.filter(price__gt=F('views'))book_gt_discount_str = ''for item in book_gt_discount:book_gt_discount_str += f"Book {item.id} has a price of {item.price} and views of {item.views}\n"# 多字段运算# 获取所有books的总价格和评分的乘积# 使用 F() 表达式在 annotate 中books = models.Book.objects.annotate(total_price=F('price') * F('views'))str_books = ''for item in books:str_books += f"Book {item.id} has total price {item.total_price}\n"# 查询时对字段进行运算# 获取book的价格大于其views加500的书籍high_books = models.Book.objects.filter(price__gt=F('views') + 500.00)high_books_str = ''for item in high_books:high_books_str += f"Book {item.id} has a price of {item.price}\n"return HttpResponse(f"book_gt_discount: <br>{book_gt_discount_str}<br>"f"str_books: <br>{str_books}<br>"f"high_books_str: <br>{high_books_str}",content_type="text/html; charset=utf-8")path('someOtherInfo', views.someOtherInfo, name='someOtherInfo'),

访问链接http://127.0.0.1:8000/article/someOtherInfo
在这里插入图片描述

5.Q() 查询

1.定义

Q() 对象来自 django.db.models,用于创建复杂的查询条件。你可以使用它来结合多个条件,执行与(AND)或或(OR)操作,甚至是非(NOT)操作,尤其是在需要执行“OR”操作或者需要多个条件组合时非常有用。Q() 对象使得构建复杂的查询变得更加灵活和强大,
使用前还是先导入

from django.db.models import Q

2.查询

定义方法和路由

def searchByq(request):# 按价格和阅读量查询书籍# 注意:Q() 函数用于构建复杂的查询条件,可以与其他条件组合使用# 这里的 Q() 函数与 price__gt 条件组合使用,表示价格大于 500.00# 与 views__gt 条件组合使用,表示阅读量大于 1books_and = models.Book.objects.filter(Q(price__gt=500.00) & Q(views__gt=1))books_and_str = ''for item in books_and:books_and_str += f"Book {item.id} has a price of {item.price} and views of {item.views}\n"# 按价格或阅读量查询书籍# 这里的 Q() 函数与 price__gt 条件组合使用,表示价格大于 500.00# 与 views__gt 条件组合使用,表示阅读量大于 1books_or = models.Book.objects.filter(Q(price__gt=500.00) | Q(views__gt=1))books_or_str = ''for item in books_or:books_or_str += f"Book {item.id} has a price of {item.price} and views of {item.views}\n"# 按价格范围查询书籍# 这里的 Q() 函数与 price__range 条件组合使用,表示价格在 500.00 到 1000.00 之间books_range = models.Book.objects.filter(Q(price__range=(500.00, 1000.00)))books_range_str = ''for item in books_range:books_range_str += f"Book {item.id} has a price of {item.price}\n"# not 查询 这里使用的 ~Q() 函数表示价格不大于 500.00books_not = models.Book.objects.filter(~Q(price__gt=500.00))books_not_str = ''for item in books_not:books_not_str += f"Book {item.id} has a price of {item.price}\n"return HttpResponse(f"books_and_str: <br>{books_and_str}<br>"f"books_or_str: <br>{books_or_str}<br>"f"books_range_str: <br>{books_range_str}"f"books_not_str: <br>{books_not_str}",content_type="text/html; charset=utf-8")path('searchByq', views.searchByq, name='searchByq'),

访问链接http://127.0.0.1:8000/article/searchByq
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/427623.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣 2529.正整数和负整数的最大计数

文章目录 题目介绍解法 题目介绍 解法 采用红蓝染色体法&#xff0c;具体介绍参考 红蓝染色体法 通过红蓝染色体法可以找到第一个大于大于target的位置&#xff0c;使所以本题可以找第一个大于0的位置&#xff0c;即负整数的个数&#xff1b;数组长度 - 第一个大于1的位置即正…

【踩坑】装了显卡,如何让显示器从主板和显卡HDMI都输出

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 背景介绍 装了显卡后&#xff0c;开机默认是从显卡的HDMI输出&#xff0c;但这很不方便。如何让视频仍然从主板输出&#xff1f;或者说让显卡HDMI和主板…

切线空间:unity中shader切线空间,切线矩阵,TBN矩阵 ,法线贴图深度剖析

unity中shader切线空间 看了网上各种解释&#xff0c;各种推理。直接脑袋大。感觉复杂的高大上。当深入了解后&#xff0c;才发是各种扯淡。 一切从模型法向量开始 在shader中&#xff0c;大部分的光照计算都是与法向量有关。通过法向量和其他向量能计算出模型在光线照射下的…

MyBatis-Plus分页查询、分组查询

目录 准备工作1. 实体类2. Mapper类3. 分页插件4. 数据 分页查询1. 使用条件构造器2. 使用自定义sql 分组查询1. 分组结果类2. 自定义sql3. 测试类 准备工作 1. 实体类 对地址字段address使用字段类型转换器&#xff0c;将List转为字符串数组保存在数据库中 package com.exa…

【CSS Tricks】一种基于AV1视频格式的现代图像格式-AVIF

引言 AV1图像文件格式&#xff08;英语&#xff1a;AV1 Image File Format&#xff0c;简称AVIF&#xff09;是由开放媒体联盟&#xff08;AOM&#xff09;开发&#xff0c;采用AV1视讯编码技术压缩图像的一种图像文件格式&#xff0c;能用来储存一般的图像和动态图像。AVIF和苹…

torch.embedding 报错 IndexError: index out of range in self

文章目录 1. 报错2. 原因3. 解决方法 1. 报错 torch.embedding 报错&#xff1a; IndexError: index out of range in self2. 原因 首先看下正常情况&#xff1a; import torch import torch.nn.functional as Finputs torch.tensor([[1, 2, 4, 5], [4, 3, 2, 9]]) embedd…

【Git原理与使用】版本管理与分支管理(1)

目录 一、基本操作 1、初识Git 2、Git安装[Linux-centos] 3、Git安装[ Linnx-ubuntu] 4、创建git本地仓库 5、配置Git 6、认识工作区、暂存区、版本库 7、添加文件 8、查看历史提交记录 9、查看.git文件目录结构 10、查看版本库对象的内容 11、小结&#xff08;在本地的.git仓库…

JVM常用参数配置

JVM常用参数配置 简单的java命令后面跟上配置参数。 -XX&#xff0c;JVM启动参数的一种类型&#xff0c;属于高级。 &#xff0c;开启的意思 &#xff1a;&#xff0c;设置具体参数 #jvm启动参数不换行 #设置堆内存 -Xmx4g -Xms4g #指定GC算法 -XX:UseG1GC -XX:MaxGCPauseM…

Qt_多元素控件

目录 1、认识多元素控件 2、QListWidget 2.1 使用QListWidget 3、QTableWidget 3.1 使用QListWidget 4、QTreeWidget 4.1 使用QTreeWidget 5、QGroupBox 5.1 使用QGroupBox 6、QTabWidget 6.1 使用QTabWidget 结语 前言&#xff1a; 在Qt中&#xff0c;控件之间…

《深度学习》—— 神经网络模型对手写数字的识别

神经网络模型对手写数字的识别 import torch from torch import nn # 导入神经网络模块 from torch.utils.data import DataLoader # 数据包管理工具&#xff0c;打包数据, from torchvision import datasets # 封装了很多与图像相关的模型&#xff0c;数据集 from torchvi…

分布式事务seata

文章目录 CAP理论BASE 理论seata解决分布式事务seata重要对象XA模式AT模式TCC模式saga模式 CAP理论 CAP理论指出在分布式系统中三个属性不可能同时满足。 Consistency 一致性&#xff1a;在分布式的多个节点&#xff08;副本&#xff09;的数据必须是一样的&#xff08;强一致…

展锐平台的手机camera 系统开发过程

展锐公司有自己的isp 图像处理引擎&#xff0c;从2012 年底就开始在智能手机上部署应用。最初的时候就几个人做一款isp的从hal 到kernel 驱动的完整软件系统&#xff0c;分工不是很明确&#xff0c;基本是谁擅长哪些就搞哪些&#xff0c;除了架构和编码实现之外&#xff0c;另外…

软硬件项目运维方案(Doc原件完整版套用)

1 系统的服务内容 1.1 服务目标 1.2 信息资产统计服务 1.3 网络、安全系统运维服务 1.4 主机、存储系统运维服务 1.5 数据库系统运维服务 1.6 中间件运维服务 2 运维服务流程 3 服务管理制度规范 3.1 服务时间 3.2 行为规范 3.3 现场服务支持规范 3.4 问题记录规范…

【数据结构】排序算法---基数排序

文章目录 1. 定义2. 算法步骤2.1 MSD基数排序2.2 LSD基数排序 3. LSD 基数排序动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 ⚠本节要介绍的不是计数排序 1. 定义 基数排序&#xff08;英语&#xff1a;Radix sort&#xff09;是一种非比较型的排序算法&…

秋招常问的面试题:Cookie和Session的区别

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

LeetCode[中等] 3. 无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 思路&#xff1a;滑动窗口&#xff0c;设置左右指针left与right&#xff0c;maxLength存储长度 利用HashSet性质&#xff0c;存储滑动窗口中的字符 如果没有重复的&#xff0c;那么right继续向…

LeetCode_sql_day28(1767.寻找没有被执行的任务对)

描述&#xff1a;1767.寻找没有被执行的任务对 表&#xff1a;Tasks ------------------------- | Column Name | Type | ------------------------- | task_id | int | | subtasks_count | int | ------------------------- task_id 具有唯一值的列。 ta…

无人机企业合法运营必备运营合格证详解

无人机企业运营合格证&#xff0c;是由国家相关航空管理部门&#xff08;如中国民用航空局或其授权机构&#xff09;颁发的&#xff0c;用于确认无人机企业具备合法、安全、高效运营无人机能力的资质证书。该证书是无人机企业开展商业运营活动的必要条件&#xff0c;标志着企业…

原生+jquery写自动消失的提示框

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>自动消失消息提示</title> <style>/…

信息安全数学基础(9)素数的算数基本定理

前言 在信息安全数学基础中&#xff0c;素数的算数基本定理&#xff08;也称为唯一分解定理或算术基本定理&#xff09;是一个极其重要的定理&#xff0c;它描述了正整数如何唯一地分解为素数的乘积。这个定理不仅是数论的基础&#xff0c;也是许多密码学算法&#xff08;如RSA…