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

Django装饰器报错:wrapper()收到意外关键字参数'id'

解决Django自定义装饰器处理带关键字参数视图的报错问题

这个问题我之前在做Django项目时也踩过坑!核心原因是你自定义的login_required装饰器结构不对,没办法正确处理视图接收的关键字参数(比如路由里的id),导致触发TypeError。

问题根源分析

你原来的装饰器写法直接把view_function, request, *args, **kwargs作为顶层函数的参数,还错误地加了@decorator(这个完全没必要)。当Django路由把id作为关键字参数传递给视图时,你的装饰器没有对应的逻辑去接收和传递这些关键字参数,自然就会报“意外的关键字参数”错误。

正确的装饰器写法

Django的视图装饰器需要是嵌套函数结构:外层函数接收被装饰的视图,内层包装函数处理请求验证,并完整传递所有参数给原视图。

基础修复版本

from django.shortcuts import redirect
from django.conf import settings

def login_required(view_function):
    def wrapper(request, *args, **kwargs):
        # 打印参数,方便调试(可选)
        print(f"位置参数: {args}")
        print(f"关键字参数: {kwargs}")
        
        if not request.user.is_authenticated():
            return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
        # 把所有参数原封不动传给原视图
        return view_function(request, *args, **kwargs)
    return wrapper

优化版本(保留原视图元信息)

建议加上functools.wraps,它会保留原视图函数的名称、文档字符串等元信息,避免Django反向解析或其他依赖函数元信息的功能出问题:

from django.shortcuts import redirect
from django.conf import settings
from functools import wraps

def login_required(view_function):
    @wraps(view_function)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated():
            return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
        return view_function(request, *args, **kwargs)
    return wrapper

为什么这样能解决问题?

  • 内层的wrapper函数用*args捕获所有位置参数,**kwargs捕获所有关键字参数(比如路由里的id)
  • 验证通过后,把这些参数完整传递给原视图函数,确保视图能拿到需要的id参数
  • @wraps(view_function)让装饰后的视图保留原有的标识,避免潜在的兼容性问题

修改完装饰器后,你的detail(或者路由里的new)视图就能正常接收id参数,不会再触发类型错误了。

内容的提问来源于stack exchange,提问作者Андрей Чупрына

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:06:03