Python 制作自定义django视图装饰器时遇到问题(使用args)
所以我读了所有类似的问题,并抄袭了他们写的内容,但我仍然有问题。所以我想要这样的东西Python 制作自定义django视图装饰器时遇到问题(使用args),python,django,decorator,python-decorators,Python,Django,Decorator,Python Decorators,所以我读了所有类似的问题,并抄袭了他们写的内容,但我仍然有问题。所以我想要这样的东西 # Yes, I know django has one but I want to make my own @rate_limit(seconds=10) myview(request, somearg, *args, **kwargs): # Return a response ... def rate_limit(seconds=10): def decorator(view)
# Yes, I know django has one but I want to make my own
@rate_limit(seconds=10)
myview(request, somearg, *args, **kwargs):
# Return a response
...
def rate_limit(seconds=10):
def decorator(view):
def wrapper(request, *args, **kwargs):
# Do some stuff
return view(request, *args, **kwargs)
return wrapper
return decorator
当我运行它时,我得到了错误
decorator() got an unexpected keyword argument 'somearg'
所以我附加了decorator来接收args和kwargs并得到这个错误
# New decorator signature
def decorator(view, *args, **kwargs)
和错误
'function' object has no attribute 'status_code'
编辑:
因此,解决办法是使用。谢谢玛蒂恩·皮特斯
@rate_limit()
而不是
@rate_limit
您的第一次尝试效果很好,但您可能忘记调用
rate\u limit()
decorator工厂
换句话说,如果执行以下操作,则会出现第一个错误:
@rate_limit
def myview(request, somearg, *args, **kwargs):
而不是:
@rate_limit(seconds=10)
def myview(request, somearg, *args, **kwargs):
您也确实希望在Django中使用的decorator上使用,特别是如果您想将其与其他Django decorator(如csrf\u-employ
)混合使用:
from functools import wraps
def rate_limit(seconds=10):
def decorator(view):
@wraps(view)
def wrapper(request, *args, **kwargs):
# Do some stuff
return view(request, *args, **kwargs)
return wrapper
return decorator
这可确保将“待包装”函数上设置的任何属性正确复制到包装器。Hrm,这些错误似乎都没有意义。您确实希望使用
functools.wrapps()
来装饰wrapper()
:从functools导入wrapps
,然后@wrapps(view)
装饰def wrapper(…)
。只需将def decorator(view):
def decorcorator(view,*args,**kwargs):@kartikr:这不是问题。这是不可能的,因为只传递了修饰函数来修饰。我强烈怀疑这不是OP运行的完整代码。@karthikr:这解决了错误的问题。我怀疑OP没有给装饰厂打电话<代码>@rate\u limit与@rate\u limit(10)
@karthikr:不,你不能。它是一家装饰工厂。它生产装饰工decorator()
是这里的实际decorator。这就成功了!我的意思是,在向decorator添加args和kwargs之后再向decorator添加()。为什么我必须像其他装饰师一样将其命名为@rate\u limit(),而不是@rate\u limit?或者,如果需要参数,是否总是需要括号?@JaredJoke:rate\u limit()
是一个装饰器工厂。它生成实际的装饰器(返回装饰器
),允许您基于参数构建不同的装饰器rate\u limit(10)
返回一个装饰器,rate\u limit(20)
返回另一个装饰器。Python然后使用返回的decorator
来实际修饰myview()
视图函数。@Jared笑话:@some\u expression
实际上只是指:执行some\u expression
,然后获取结果(必须是可调用的),并用要修饰的函数调用它。所以rate\u limit(10)
返回decorator
,它被称为传入myview
,而decorator
反过来返回wrapper()
来替换myview
函数。django如何使@login\u required
和@login\u required()
work?。@datagrade:by取决于您是否传入了位置函数
参数或传入了其他参数。