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

Django报request参数非HttpRequest实例(OrderedDict)错误排查

报错根因

这个报错和你贴出的服务层业务逻辑无关,核心触发原因是同名函数覆盖导致的调用错误:

  1. 你先通过from custom_label.services.custom_label_svc import update_label导入了服务层的更新函数
  2. 紧接着你定义的视图函数本身也命名为update_label,直接在全局作用域覆盖了之前导入的服务层函数
  3. 当你执行update_label(payload.validated_data)时,实际调用的是视图函数本身,而非服务层函数。视图函数的第一个位置参数要求传入django.http.HttpRequest实例,你传入的是序列化器校验后返回的OrderedDict类型数据,自然触发参数类型不匹配的报错。
  4. 其他业务模块运行正常,是因为那些模块的视图函数名和导入的服务层函数名不存在重名,没有触发覆盖问题。

另外你贴的服务层代码还存在几个会导致线上异常的隐患,和当前报错无关但必须修复:

  • 数据库连接、游标在模块全局作用域初始化,会被所有请求共享,服务长时间运行后会出现连接超时、事务错乱、游标状态污染等问题
  • SQL语句通过字符串格式化拼接参数,存在明确的SQL注入风险
  • 写操作没有事务提交逻辑,即使SQL执行成功,修改也不会实际落库
  • 函数返回值标注错误,cursor.rowcount是整数类型,不是dict
修复方案

1. 解决命名冲突(修复当前报错)

两种方案选其一即可:

方案一:给导入的服务层函数加别名

修改导入语句,避免和视图函数重名:

# 视图层修改导入语句
from custom_label.services.custom_label_svc import update_label as update_label_svc

@api_view(["POST"])
@authorize
def update_label(request) -> JsonResponse:
    try:
        payload = ValidateUpdateLabel(data=request.data)
        if payload.is_valid():
            # 调用时使用别名
            data = update_label_svc(payload.validated_data)
            # 其余业务逻辑保持不变

方案二:修改视图函数名

将视图函数重命名为不和服务层函数冲突的名称,注意同步修改路由配置中对该视图的引用:

from custom_label.services.custom_label_svc import update_label

@api_view(["POST"])
@authorize
def update_label_view(request) -> JsonResponse: # 修改视图函数名
    try:
        payload = ValidateUpdateLabel(data=request.data)
        if payload.is_valid():
            data = update_label(payload.validated_data)
            # 其余业务逻辑保持不变

2. 修复服务层数据库逻辑隐患

调整服务层代码,将数据库连接初始化移到函数内部,改用参数化查询,补充事务提交/回滚和资源释放逻辑:

from basic_files.database_connections import connect_to_postges

def update_label(params: dict) -> int:
    app_id = params.get('appid')
    label_name = params.get('label_name')
    updated_label_icon = params.get('updated_label_icon')
    
    conn = None
    cursor = None
    try:
        # 每次请求单独创建连接,避免连接复用问题
        conn = connect_to_postges()
        cursor = conn.cursor()
        # 参数化查询,杜绝SQL注入
        sql = "UPDATE label SET icon = %s WHERE appId = %s AND name = %s"
        cursor.execute(sql, (updated_label_icon, app_id, label_name))
        conn.commit() # 写操作必须提交事务才会落库
        return cursor.rowcount
    except Exception as e:
        if conn:
            conn.rollback() # 异常时回滚事务
        raise e
    finally:
        # 释放游标和连接
        if cursor:
            cursor.close()
        if conn:
            conn.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:45:32