2010-04-22 80 views
40

我试图写一个Django的“工作人员只有”装饰,但我似乎无法得到它的工作: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 

试图follow lead from here。我越来越:

'WSGIRequest' object has no attribute '__name__'

但是,如果我把这些三线出来,我只是得到一个无用的“内部服务器错误”。我在这里做错了什么?

回答

10

装饰功能的这种风格使用参数化装饰 - 例如,当你这样做:

@staffonly(my_arguments) 
def function(request): 
    blah 

如果你没有实际调用外部函数,即你使用它是这样的:

@staffonly 
def function(request): 

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

+0

哦...那我怎么解决这个问题? – mpen 2010-04-22 20:27:21

+1

我开始明白,所以如果我在我看来有多个功能,我必须在他们每个人面前添加@staffonly? – 2014-02-19 13:46:41

128

这个装饰已经存在了

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

@staff_member_required 

干线: http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/views/decorators.py

+0

哦......很酷。我仍然想知道如何编码它;) – mpen 2010-04-22 20:26:29

+1

另外,问题在于它不显示指示问题出在哪里的错误消息。我的客户很有可能尝试访问没有员工用户帐户的员工页面。 – mpen 2010-04-22 20:30:15

+0

卢克(或马克),使用源!在'django/contrib/admin/views/decorators.py'(1.1.1版本的第26行)中,你会发现这个函数,并且在第71行,你会看到'if user.is_active and user.is_staff:'这给出了大拇指向上/向下的决定。这个特定的装饰器比正常情况稍微复杂的唯一原因是它会触发登录序列作为副作用。如果你需要做更多的事情(例如不同的错误消息),你可以随时创建一个副本,然后在适当的时候调用你自己的装饰器。 – 2010-04-22 20:36:08

2

对于类基础观 S,你可以装饰视图类的调度方法,像这样:

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): 
    ...