装饰器失败时显示错误消息

时间:2013-05-04 13:50:54

标签: django python-decorators

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

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)

1 个答案:

答案 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结果远这里更有效率。

相关问题