3

装饰器工作正常,但如果用户不属于任何所需的组,我想显示一条错误消息(我想使用消息框架)。这是装饰器:

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')

我尝试使用此代码段来使用消息框架(因为这需要请求对象),但它意识到消息框架中间件并未安装在装饰器中。

我愿意改变一切:)

更新:

我在找什么:

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)
4

1 回答 1

1

我认为在这个用例中你真的不需要 threadlocals。通常当 threadlocals 似乎是进入 Django 应用程序的唯一方法时,可能会有一些结构错误的上下文层。与threadlocals进行比较,我宁愿复制user_passes_test然后修改它以传递requestin_groups(如果不修改代码,我们无法轻松传递request给。检查问题:How to pass Django request object in user_passes_test decorator callable function。)(也许这张票?)is_groupuser_passes_test

此外,bool(user.groups.filter(name__in=group_names))会导致在确定存在之前将项目检索到 DB 适配器和 Python 实例,因此使用exists()并因此user.groups.filter(name__in=group_names).exists()直接从 DB 后端返回 bool 结果在这里效率更高。

于 2013-05-04T17:09:53.157 回答