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

Django聚合查询报错UnboundLocalError:current变量未赋值即引用

Django聚合操作触发UnboundLocalError的解决办法

使用Django对查询集执行平均值、求和等聚合操作时,根据period参数匹配对应时间段计算总和与平均值,运行时触发错误:UnboundLocalError: local variable 'current' referenced before assignment。

原代码

def metrics(request):
    email = request.data.get("email")
    period = request.data.get("period") # [0,1,2,3 : day, week, month, year]

    today = date.today()
    weekday = date.isoweekday(today)
    month = today.month
    year = today.year
    current_week = date.isocalendar(today).week

    store = Store.objects.get(account__email=email)
    sales = Order.objects.filter(store=store)

    match period:
        case 0:
            # 'Today'
            current = sales.filter(created__week_day=weekday)
            past = sales.filter(created__week_day=weekday - 1)
        case 1:
            # 'This week'
            current = sales.filter(created__week=current_week) 
            past = sales.filter(created__week=current_week - 1)
        case 2:
            # 'This month'
            current = sales.filter(created__month=month)
            past = sales.filter(created__month=month - 1)
        case 3:
            # 'This year'
            current = sales.filter(created__year=year)
            past = sales.filter(created__year=year - 1)

    current_total = current.aggregate(Sum('products_total'))['products_total__sum']
    past_total = past.aggregate(Sum('products_total'))['products_total__sum']

    current_average = current.aggregate(Avg('products_total'))['products_total__avg']
    past_average = past.aggregate(Avg('products_total'))['products_total__avg']

    current_count = current.count()
    past_count = past.count()

打印的相关值

# today:  2023-05-20
# weekday:  6
# month:  5
# year: 2023
# current week:  20

Order模型定义

class Order(models.Model):
    products_total = models.DecimalField(max_digits=10, decimal_places=2, default=0.0)
    ...

尝试改用if/elif语句仍出现相同错误,不知如何修改。


问题根源

错误的核心原因是:当period参数不是0、1、2、3中的有效值时,current和past变量从未被赋值。比如period为None、其他数字或非法值时,match语句的所有case都不匹配,导致后续代码调用current.aggregate()、past.count()等方法时,变量未定义,触发UnboundLocalError。

修复方案

有两种核心修复思路,任选其一即可:

思路1:提前初始化变量

在match语句前,给current和past设置默认值(空查询集),确保无论period是否合法,变量都已定义:

# 在match语句前添加
current = sales.none()
past = sales.none()

match period:
    # 原有case逻辑保持不变

思路2:添加默认case处理非法period

给match语句添加case _:分支,处理所有不符合0-3的情况,比如直接返回错误响应:

match period:
    # 原有case 0-3逻辑保持不变
    case _:
        # 拦截非法参数,返回错误
        return JsonResponse({"error": "Invalid period parameter"}, status=400)
        # 或者设置默认查询集
        # current = sales.none()
        # past = sales.none()

额外建议

可以在代码开头先校验period的合法性,提前拦截非法参数:

period = request.data.get("period")
if period not in [0,1,2,3]:
    return JsonResponse({"error": "Period must be 0,1,2,3"}, status=400)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:12:35