首页 > 编程问答 >用 Count 注释的查询集正在计算错误发生次数

用 Count 注释的查询集正在计算错误发生次数

时间:2024-07-24 04:15:03浏览次数:4  
标签:python django

我想计算名称在查询集中出现的次数:

items = self.get_queryset()
items = items.values("name").annotate(count=Count("name")).order_by("-count")

其中 get_queryset() 返回带有一些过滤器和注释的项目列表。

 def get_queryset(self):
        return (
            self.queryset.filter(...)
            .annotate(...)
            .order_by("id")
            .distinct()
        )

这应该返回如下查询集:

[
  {
    "name": "Item 1",
    "count": 1
  },
  {
    "name": "Item 2",
    "count": 4
  },
  {
    "name": "Item 3",
    "count": 12
  },
]

这会返回一些错误的计数,例如,应该出现 1 次的项目计数为 17,而应该出现 3 次的项目计数为 51,由于某种原因将其乘以 17。我该如何解决这个问题?


问题出在你对已经注释和过滤的查询集应用 values('name') annotate(count=Count('name')) 的方式。 当你在已经注释的查询集上使用 values() 时,它会改变分组,导致计数不准确。

以下是解决方法以及原因:

问题:

  1. 初始注释和 distinct(): 你的 get_queryset() 方法中的初始注释和 .distinct() 可能会创建具有相同“名称”但其他字段不同的行。
  2. values('name') 更改分组: 当你应用 values('name') 时,你将查询集分组到仅具有 "name" 字段的对象,从而丢弃其他注释。这会在初始注释和 .distinct() 之前有效地对你的数据进行分组,从而导致计数不准确。

解决方案:

在使用 values('name') 之前 执行计数,或在子查询中执行计数:

方法 1:在 values() 之前计数

def get_queryset(self):
    items = (
        self.queryset.filter(...)
        .values("name")  # 首先按名称分组
        .annotate(count=Count("id"))  # 然后计算出现次数
        .order_by("-count")
    )
    return items 

方法 2:使用子查询

from django.db.models import Subquery, OuterRef

def get_queryset(self):
    # 对初始查询集执行注释和过滤器
    annotated_items = self.queryset.filter(...).annotate(...)

    # 使用子查询计算每个名称的计数
    items = (
        self.queryset.filter(name=OuterRef('name'))
        .values('name')
        .annotate(count=Count('*'))
    )

    # 使用 Subquery 将计数注释到主查询集中
    items = annotated_items.annotate(count=Subquery(items.values('count')[:1])) 

    return items.order_by("-count")

说明:

  • 方法 1 通过首先对名称进行分组,然后计算每个名称的 id 数量来更正分组。
  • 方法 2 使用子查询来计算每个名称的计数,而不会影响初始查询集的注释或过滤器。然后,使用 Subquery 将此计数应用于主查询集。

通过这些调整,你的计数应该会准确反映每个名称的出现次数。选择最适合你的代码结构和性能需求的方法。

标签:python,django
From: 78785254

相关文章

  • python 以及将数组传递给函数的问题
    我需要求解一些常微分方程$\frac{dy}{dx}=f(x)=x^2ln(x)$并继续在限制0之间创建数组xpt。<=xpt<=2因为我必须小心xpt=0,所以我将函数定义如下deff(x):ifx<=1.e-6:return0.else:returnnp.square(x)*np.log(x)我的调用程序读取Np......
  • 如果 Python 脚本正在使用文件夹,如何在文件资源管理器中进行更改时防止 Windows 的“
    我有一个简单的脚本,显示在QTreeView中的QListView中选择的目录的内容,我想添加打开文件资源管理器的功能,以让用户编辑目录内的内容。但是,添加新的文件夹和文件可以,但删除或移动文件夹或文件会提示“文件夹正在使用”错误:此操作无法完成,因为该文件已在另一个程......
  • 如何使用 Python API 获取每个模型的活跃用户列表、最后登录信息
    我想通过PythonAPI获取我的dbt项目的所有模型中的活动或非活动用户列表。这可能吗?我尝试列出模型,但无法获取用户信息,如用户名、项目、以及上次活动或上次登录。不幸的是,dbt本身并不跟踪你所寻找的用户活动数据(最后登录、活跃用户等)。dbt的主要功能是转换数据,而不......
  • Python tkinter 窗口不断关闭,我不知道为什么
    我正在尝试制作一个有趣的小程序,其中每小时左右就会有一只毛茸茸的动物走过屏幕。我有一个主窗口,它启动一个循环,每小时左右播放一次动画/声音,但是在口袋妖怪第一次完成行走后,整个程序就会结束。我认为这可能与我设置tkinter窗口的方式有关,但我无法弄清楚。我认为在这里包含......
  • 用于自动访问 MongoDB Atlas CLI 的 Python 脚本
    我想编写一个Python脚本,以便普通用户可以访问他的数据库并从他的终端执行CRUD操作。我正在查看官方文档,但我有点迷失。有人可以给我指点基本教程来开始吗?当然,以下是如何构建Python脚本来访问MongoDBAtlasCLI的基本教程:先决条件:MongoDBAtlas......
  • Python实现简单学生登陆系统
     代码:importhashlibclassStudent:def__init__(self,username,password):#初始化学生对象,存储用户名和加密后的密码self.username=usernameself.password=hashlib.sha256(password.encode()).hexdigest()defcheck_passwo......
  • python猜数字游戏
    好的,下面是一个简单的小游戏代码示例,使用Python编写。这个游戏是一个猜数字游戏,玩家需要猜一个1到100之间的随机数。importrandomdefguess_number_game():print("欢迎来到猜数字游戏!")print("我已经想好了一个1到100之间的数字,请你猜一猜。")secret_num......
  • Django教程(004):基于orm操作数据库的用户管理实现
    文章目录1、功能需求2、展示用户列表2.1添加url2.2创建视图2.3编写html页面3、添加用户3.1添加url3.2跳转到添加页面3.3编写添加用户页面3.4添加用户3.5实现效果3.6页面优化4、删除用户4.1添加删除用户按钮4.2添加删除url4.3删除用户4.4实现效果5、完整......
  • 【Python正则表达式】:文本解析与模式匹配
    文章目录1.正则表达式2.re模块3.修饰符3.元字符3-1字符匹配元字符3-2重复次数限定元字符3-3字符集合匹配元字符3-4分组元字符3-5边界匹配元字符3-6字符类别匹配元字符4.技巧4-1贪婪与非贪婪5.案例1.正则表达式正则表达式面向什么样的问题?1、判断一个字......
  • 仅需增加2行代码,Python量化策略速度提升20+倍!
    今天分享一个Python量化策略加速的小技巧,不用修改原有代码,只需在原有代码里新增2行,策略执行速度便可能提高20+倍,正文开始~现如今,无论是入门量化投资,还是做数据分析、机器学习和深度学习,Python成为了首选编程语言,直观的原因就是容易上手和资源丰富,但Python有个根深蒂固的标签,......