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

如何在Django QuerySet上执行自定义聚合计算请假总天数?

用Django ORM计算符合规则的总请假天数

嘿,这个需求用Django自带的Case和When表达式就能轻松搞定,完全适配你要的「半天假算0.5天,全天假算1天」的规则,而且是在数据库层面完成计算,效率拉满!

步骤分解:

  1. 先导入需要的ORM工具
    首先要引入Django的条件表达式和聚合函数:

    from django.db.models import Case, When, Value, FloatField, Sum
    
  2. 给每个请假条目标注对应天数
    通过annotate给每个LeaveEntry对象添加一个day_value字段,根据half_day的值返回对应的天数:

    leave_entries = LeaveEntry.objects.annotate(
        day_value=Case(
            # 当half_day为True时,计0.5天
            When(half_day=True, then=Value(0.5)),
            # 其他情况默认计1天
            default=Value(1.0),
            # 指定输出类型为浮点型,避免整数运算问题
            output_field=FloatField()
        )
    )
    
  3. 聚合计算总天数
    如果要直接得到总天数,在上面的基础上用aggregate做求和操作,同时处理空数据的情况(避免返回None):

    total_days = leave_entries.aggregate(total=Sum('day_value'))['total'] or 0.0
    

结合你的过滤场景

你之前是通过filter筛选特定的请假请求,把过滤、标注、聚合合并成一行代码更简洁:

total_unapproved_leave_days = LeaveEntry.objects.filter(leave_request=self.unapproved_leave).annotate(
    day_value=Case(
        When(half_day=True, then=Value(0.5)),
        default=Value(1.0),
        output_field=FloatField()
    )
).aggregate(total_days=Sum('day_value'))['total_days'] or 0.0

为什么这么做?

这种方式是让数据库来处理条件判断和求和,比把所有数据拉到Python里循环计算要高效得多,尤其是当你的请假条目数量很大的时候,能显著减少内存占用和处理时间。

内容的提问来源于stack exchange,提问作者tread

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:39:01