Having trouble making a custom django view decorator (with args)

做~自己de王妃 提交于 2020-01-12 10:19:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!