我正在使用Django Message Framework向用户以及@login_required我的一个视图上的装饰器显示消息.因此,如果用户在未登录的情况下尝试访问某个视图,他们就会被踢到登录页面.我如何向登录页面添加错误消息"为了做...你必须登录".我不能像往常一样在视图中添加它,因为未登录的用户永远不会到达那里.
Lva*_*Ree 17
我花了一段时间才弄清楚这样做的好方法,但我认为我有一个实现,基于Daniel Roseman的回答
我做的第一件事是创建一个装饰器,当用户没有登录时设置消息,就像login_required一样.
所以我写了login_required_message:
try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps # Python 2.4 fallback.
from django.utils.decorators import available_attrs
from django.contrib import messages
default_message = "Please log in, in order to see the requested page."
def user_passes_test(test_func, message=default_message):
"""
Decorator for views that checks that the user passes the given test,
setting a message in case of no success. The test should be a callable
that takes the user object and returns True if the user passes.
"""
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
if not test_func(request.user):
messages.error(request, message)
return view_func(request, *args, **kwargs)
return _wrapped_view
return decorator
def login_required_message(function=None, message=default_message):
"""
Decorator for views that checks that the user is logged in, redirecting
to the log-in page if necessary.
"""
actual_decorator = user_passes_test(
lambda u: u.is_authenticated, #fixed by removing ()
message=message,
)
if function:
return actual_decorator(function)
return actual_decorator
Run Code Online (Sandbox Code Playgroud)
通过此实现,您现在可以注释您的视图方法,如下所示:
from decorators import login_required_message
from django.contrib.auth.decorators import login_required
@login_required_message(message="You should be logged in, in order to see the index!")
@login_required
def index(request):
pass
Run Code Online (Sandbox Code Playgroud)
现在首先设置消息,然后执行重定向.
但实际上我并不想在任何地方添加login_required_message装饰器.只有一个装饰器会好得多.所以让我们链接它们(只需在login_required_message之后将它添加到你的decorator.py文件中):
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required
def login_required_message_and_redirect(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None, message=default_message):
if function:
return login_required_message(
login_required(function, redirect_field_name, login_url),
message
)
return lambda deferred_function: login_required_message_and_redirect(deferred_function, redirect_field_name, login_url, message)
Run Code Online (Sandbox Code Playgroud)
我花了一段时间来弄清楚最后一行; 但是lambda要救了!
现在你可以用login_required_message_and_redirect替换两个装饰器:几乎就在那里!因为实际上我想在任何地方使用这个新的login_required_message方法,我为login_required添加了一个猴子补丁,它随处可见(再次添加到decorators.py文件的底部)!
from django.contrib.auth import decorators
setattr(decorators, 'login_required', login_required_message_and_redirect)
Run Code Online (Sandbox Code Playgroud)
这让我打电话:
# a message will appear, since login_required is monkey patched
@login_required
def logout(request):
pass
# or customize the message per view
@login_required(message="You should be logged in message! Available after monkey patch")
def index(request):
pass
Run Code Online (Sandbox Code Playgroud)
Dan*_*man 13
没有任何明显的方法.我唯一想到的是编写自己的装饰器版本,在重定向之前将消息放入会话,然后获取登录模板以显示会话中的消息.
您需要使用代码django.contrib.auth.decorators,特别是user_passes_test函数 - 添加消息之前必须使用的位return HttpResponseRedirect.
| 归档时间: |
|
| 查看次数: |
3274 次 |
| 最近记录: |