装饰器工作正常,但如果用户不属于任何必需的组,我想显示错误消息(我想使用消息框架)。这是装饰者:
def group_required(*group_names):
"""Requires user membership in at least one of the groups passed in."""
def in_groups(user):
if user.is_authenticated():
if bool(user.groups.filter(name__in=group_names)) or user.is_superuser:
return True
return False
return user_passes_test(in_groups)
我用以下的方式称呼它:
@require_http_methods(['GET'])
@group_required('supervisor')
def home_view(request):
return render(request, 'home.html')
我尝试使用此snippet来使用消息框架(因为这需要请求对象),但它意识到消息框架中间件似乎没有安装在装饰器内。
我愿意改变一切:)
更新
我在寻找:
def group_required(request, *group_names):
"""Requires user membership in at least one of the groups passed in."""
def in_groups(user):
if user.is_authenticated():
if user.groups.filter(name__in=group_names).exists() or user.is_superuser:
return True
else:
# I'm getting:
# You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware
messages.add_message(request, messages.ERROR, 'Group is not allowed')
return False
return user_passes_test(in_groups, request)
答案 0 :(得分:1)
我不认为你在这个用例中真的需要threadlocals。通常当threadlocals似乎是进入Django应用程序的唯一方法时,可能会有一些错误结构的上下文层。与threadlocals进行比较,我希望复制user_passes_test
,然后修改它以将request
传递给in_groups
(我们无法轻松将request
传递给is_group
无需修改user_passes_test
的代码。请检查问题:How to pass Django request object in user_passes_test decorator callable function。)(也许是此票?)
此外,bool(user.groups.filter(name__in=group_names))
会导致项目在确定存在之前被检索到数据库适配器和Python实例,使用exists()
因此user.groups.filter(name__in=group_names).exists()
直接返回来自数据库后端的bool结果远这里更有效率。