问题
So, I'm pretty familiar with wrapping functions in views.py. So I've written a decorator to redirect to the default REDIRECT_URL if the user is logged in (sort of a reverse login_required
); it's based on how I've made views in the past:
def not_logged_in(redirect_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
def decorator(view_func, *args, **kwargs):
def wrapper(request, *args, **kwargs):
if not request.user.is_authenticated():
return view_func(*args, **kwargs)
else:
redirect_url = (request.REQUEST.get(redirect_field_name, redirect_url) or
settings.REDIRECT_URL)
return HttpResponseRedirect(redirect_url)
return wrapper
return decorator
However, I get the following error: 'function' object has no attribute 'status_code'
which is caused by a MiddleWare expecting an HttpResponse. When I look at the value for response
, I see that it's <function wrapper at 0x2b3a9922a500>
.
Here's how I'm calling it in urls.py
:
url(r'login/',
not_logged_in(auth_views.login),
{'authentication_form': LoginForm },
),
回答1:
Here’s my implementation of the same thing.
def logout_required(view):
def f(request, *args, **kwargs):
if request.user.is_anonymous():
return view(request, *args, **kwargs)
return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
return f
In urls.py
:
urlpatterns = patterns("",
url(r"^login/", logout_required(login), {"template_name": "users/login.html"}, "login"),
# ...
I hope this helps (unsure though).
回答2:
The first argument to a decorator should be the function that needs to be decorated.
def not_logged_in(func, redirect_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
The decorator function is also not needed. Return the wrapper function from not_logged_in.
回答3:
The way you've implemented your decorator, it is parameterised and therefore callable: that's why you've got the extra level of function that fizixx wrongly says is not required. You need to call the outer wrapper initially, in order to return the actual decorated function. So something like:
url(r'login/',
not_logged_in(auth_views.login)('/redirect/', 'redirect_field'),
{'authentication_form': LoginForm },
),
来源:https://stackoverflow.com/questions/5796897/wrapping-decorating-a-function-in-urls-py-vs-in-views-py