Django 德扬戈:员工装饰师

Django 德扬戈:员工装饰师,django,decorator,Django,Decorator,我正试图为Django编写一个“仅限员工”的装饰程序,但似乎无法使其正常工作: def staff_only(error='Only staff may view this page.'): def _dec(view_func): def _view(request, *args, **kwargs): u = request.user if u.is_authenticated() and u.is_staff:

我正试图为Django编写一个“仅限员工”的装饰程序,但似乎无法使其正常工作:

def staff_only(error='Only staff may view this page.'):
    def _dec(view_func):
        def _view(request, *args, **kwargs):
            u = request.user
            if u.is_authenticated() and u.is_staff:
                return view_func(request, *args, **kwargs)
            messages.error(request, error)
            return HttpResponseRedirect(request.META.get('HTTP_REFERER', reverse('home')))
        _view.__name__ = view_func.__name__
        _view.__dict__ = view_func.__dict__
        _view.__doc__ = view_func.__doc__
        return _view
    return _dec
试着去。我得到:

'WSGIRequest'对象没有属性'\uuuu name'


但如果我去掉这3行,我只会得到一个无用的“内部服务器错误”。我在这里做错了什么?

这种类型的装饰函数与参数化装饰器一起使用,例如:

@staffonly(my_arguments)
def function(request):
    blah
如果您没有实际调用外部函数,即您是这样使用它的:

@staffonly
def function(request):
from django.contrib.admin.views.decorators import staff_member_required
from django.utils.decorators import method_decorator


@method_decorator(staff_member_required, name='dispatch')
class ExampleTemplateView(TemplateView):
    ...

您将得到奇怪的结果,因为函数对象将被传递到装饰器中的嵌套函数中的错误函数。

此装饰器已作为

from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
主干:

对于基于类的视图,您可以如下装饰视图类的分派方法:

@staffonly
def function(request):
from django.contrib.admin.views.decorators import staff_member_required
from django.utils.decorators import method_decorator


@method_decorator(staff_member_required, name='dispatch')
class ExampleTemplateView(TemplateView):
    ...

哦那么我该如何解决这个问题呢?我开始明白了,如果我的视图中有多个函数,那么我必须在每个函数前面添加@staffonly?而且,问题是它不会显示一条错误消息来指出问题所在。我的客户很可能会尝试访问没有员工用户帐户的员工页面。Luke(或Mark),使用源代码!在
django/contrib/admin/views/decorators.py
(1.1.1版本中的第26行)中,您可以找到此函数,在第71行中,您可以看到
user.is\u active和user.is\u staff:
,它给出了向上/向下的决定。这个特殊的装饰程序比普通的要复杂一点的唯一原因是它会触发一个登录序列作为副作用。如果您需要它做更多的工作(例如不同的错误消息),您可以随时制作一份副本,然后在适当的地方调用您自己的装饰程序。@Peter:Luke是谁?在这种情况下,源代码没有太大帮助,因为它不接受装饰程序的参数,我认为这是导致我出现问题的原因。@Mark:Luke是。。。卢克·天行者!欧比-万·克诺比()是在《星球大战4》(实际上是第一部电影)中说“卢克!使用源代码!”的人。装饰器通常只接受一个参数,即要装饰的函数。如果需要添加更多参数,请签出教程。(例如)如果当前的装饰师不能满足您的需要,请复制并更改它!这就是开源的本质。我还以为是“使用原力”?可爱的文字游戏;)这不是我做的吗?我的代码看起来很像您所指的示例。。。哦,好吧。。。我想那我得自己解决了。