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

Django REST Framework API除以零导致NaN问题的解决方案咨询

解决Django REST Framework中除以零导致的API异常问题

这是数值计算里很常见的边界场景,咱们可以通过提前校验除数+友好错误反馈+代码安全优化三个维度来彻底解决,同时避免潜在的安全风险。

核心问题分析

你的代码里直接执行((sales_all - sales_p)/sales_c)*100,当sales_c为0时会触发除以零的运算,生成NaN,最终导致API返回异常(可能是500错误或不符合预期的响应)。另外还有两个隐藏问题:

  • 直接拼接用户输入的input_date到SQL语句中,存在SQL注入风险
  • 代码里出现了笔误:df5['sales_c'].loc[0]应该是df['sales_c'].loc[0],否则会抛出NameError

最优处理方案

下面是修改后的完整代码,包含所有优化点:

from rest_framework import status
from rest_framework.response import Response
from rest_framework.exceptions import ServiceUnavailable

def your_api_view(request):
    input_date = request.query_params.get('date')  # 假设从查询参数获取日期
    dept_id = request.query_params.get('dept_id')  # 假设从查询参数获取部门编号

    # 1. 使用参数化SQL避免注入风险(替换原来的字符串拼接)
    sql = "select sales_p, sales_c, sales_all from sales where dat_ref = %s and dept_id = %s"
    try:
        # 假设select_vector支持接收params参数传递查询值
        df = select_vector(sql, DB_CONNECTOR, params=(input_date, dept_id))
    except Exception:
        raise ServiceUnavailable()
    
    if df is None:
        raise ServiceUnavailable()
    
    if len(df) > 0:
        sales_p = df['sales_p'].loc[0]
        sales_c = df['sales_c'].loc[0]  # 修正原代码的df5笔误
        sales_all = df['sales_all'].loc[0]
    else:
        return Response(status=status.HTTP_204_NO_CONTENT)
    
    # 2. 提前校验除数是否为0,避免NaN异常
    if sales_c == 0:
        return Response(
            {
                'error': '无法计算销售指标百分比',
                'detail': '对应日期和部门的sales_c字段值为0,除数不能为零'
            },
            status=status.HTTP_400_BAD_REQUEST
        )
    
    # 3. 安全计算百分比,额外捕获数值转换异常
    try:
        percentage_value = ((sales_all - sales_p) / sales_c) * 100
        percentage = float("{0:.2f}".format(percentage_value))
    except (TypeError, ValueError) as e:
        return Response(
            {
                'error': '销售指标计算失败',
                'detail': f'数值计算出错:{str(e)}'
            },
            status=status.HTTP_400_BAD_REQUEST
        )
    
    return Response({'Percentage': percentage})

关键优化点说明

  • 参数化SQL查询:不再直接拼接用户输入的日期和部门编号,而是通过参数传递,彻底避免SQL注入攻击,这是后端开发的必备安全规范。
  • 提前除数校验:在计算前先判断sales_c是否为0,直接返回清晰的错误信息给用户,而不是让程序抛出未处理的异常。
  • 异常兜底处理:捕获数值转换或计算时的TypeError/ValueError,比如字段值不是数值类型的情况,确保API始终返回结构化的响应。
  • 修正代码笔误:把原代码中的df5改为df,避免不必要的NameError。

响应说明

用户遇到除数为0的情况时,会收到如下结构化响应(HTTP 400状态码):

{
    "error": "无法计算销售指标百分比",
    "detail": "对应日期和部门的sales_c字段值为0,除数不能为零"
}

这样用户能明确知道问题所在,而不是收到模糊的500错误或异常响应。

内容的提问来源于stack exchange,提问作者S.Jackson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:32:28