2010-04-22 56 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): 
    ...