You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Annotate如何使用模型自定义方法get_is_secure实现分组统计

Django 按模型方法逻辑分组统计的实现方案

Django ORM 的所有查询逻辑最终都会转换为SQL在数据库层面执行,无法直接识别Python层定义的模型实例方法,因此你定义的get_is_secure方法不能直接作为查询的分组维度,需要将方法内的判断逻辑转换为数据库可执行的条件表达式实现。

具体实现步骤

  1. 首先导入需要用到的ORM工具类:
from django.db.models import Count, Case, When, BooleanField
  1. 修改你的查询语句,先通过annotate动态生成is_secure临时字段,再执行分组统计:
indicators["studies_by_status"] = ScoringStudyLog.objects.filter(
    **studies_filters
).annotate(
    # 完全复现get_is_secure方法的判断逻辑
    is_secure=Case(
        When(scoring_status="approved", then=True),
        default=False,
        output_field=BooleanField()
    )
).values("is_secure").annotate(times=Count("id"))

补充说明

  • 上述代码中的Case/When逻辑和你定义的get_is_secure方法完全一致,生成的is_secure布尔字段就是你需要的分组维度
  • 统计计数使用Count("id")比Count("is_secure")兼容性更好,不会出现空值漏统计的问题

可选优化(高频使用场景)

如果这个is_secure判断逻辑需要频繁用到,可以将其封装到自定义模型管理器中,后续查询无需重复写条件:

# 自定义管理器
class ScoringStudyLogManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().annotate(
            is_secure=Case(
                When(scoring_status="approved", then=True),
                default=False,
                output_field=BooleanField()
            )
        )

# 给原模型绑定管理器
class ScoringStudyLog(TimeStampedModel):
    # 原有字段、方法不变
    objects = ScoringStudyLogManager()

封装完成后你原本写的查询语句就可以直接运行,不需要每次手动添加annotate逻辑。


内容的提问来源于stack exchange,提问作者Jimmy A. León

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:54:05