问题
So I've read all the similar questions and copied what they wrote but I still keep having issues. So I want something like this
# 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
When I run it I get the error
decorator() got an unexpected keyword argument 'somearg'
So I append decorator to take in args and kwargs and get this error
# New decorator signature
def decorator(view, *args, **kwargs)
and error
'function' object has no attribute 'status_code'
edit: So the solution was to use. Thanks Martijn Pieters!
@rate_limit()
instead of
@rate_limit
回答1:
Your first attempt works just fine, but you probably forgot to call the rate_limit()
decorator factory.
In other words, your first error occurs if you do this:
@rate_limit
def myview(request, somearg, *args, **kwargs):
instead of:
@rate_limit(seconds=10)
def myview(request, somearg, *args, **kwargs):
You also really want to use functools.wraps() on decorators used in Django, especially if you want to mix this with other Django decorators such as csrf_exempt
:
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
This ensures that any attributes set on the to-be-wrapped function are copied over correctly to the wrapper.
来源:https://stackoverflow.com/questions/19965036/having-trouble-making-a-custom-django-view-decorator-with-args