2010-04-22 16 views
40

Próbuję napisać „personel tylko” dekorator dla Django, ale nie wydaje się uzyskać go do pracy:Django: Staff Dekorator

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 

Próbując follow lead from here. Dostaję:

'WSGIRequest' object has no attribute '__name__'

Ale jeśli wziąć te 3 linie, ja po prostu bezużyteczne „wewnętrzny błąd serwera”. Co ja tu robię źle?

Odpowiedz

10

Ten styl funkcji dekorator jest używany z parametryzowane dekoratora - np kiedy zrobić:

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

Jeśli nie masz rzeczywiście wywołując funkcję zewnętrzną, czyli używasz go tak:

@staffonly 
def function(request): 

Otrzymasz dziwne wyniki, ponieważ obiekt funkcji zostanie przekazany do niewłaściwej funkcji zagnieżdżonej w dekoratorze.

+0

Och ... więc jak to obejść? – mpen

+1

Zaczynam rozumieć, więc jeśli mam wiele funkcji w moim widoku, muszę dodać @staffonly przed każdym z nich? –

128

ten dekorator już istnieje jako

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

@staff_member_required 

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

+0

Och ... spoko. Nadal chcę wiedzieć, jak bym go zakodować;) – mpen

+1

Problem polega również na tym, że nie wyświetla się komunikat o błędzie informujący o problemie. Moi klienci prawdopodobnie spróbują odwiedzić stronę personelu bez konta użytkownika personelu. – mpen

+0

Luke (lub Mark), użyj źródła! W 'django/contrib/admin/views/decorators.py' (wiersz 26 w wydaniu 1.1.1) znajdziesz tę funkcję, aw linii 71 zobaczysz' if user.is_active i user.is_staff: ' co daje decyzję kciuka w górę/w dół. Jedynym powodem, dla którego ten konkretny dekorator jest nieco bardziej skomplikowany niż zwykle, jest to, że może wywołać sekwencję logowania jako efekt uboczny. Jeśli potrzebujesz więcej (np. Różnych komunikatów o błędach), zawsze możesz utworzyć kopię, a następnie w razie potrzeby wywołać własnego dekoratora. –

2

Dla klasy opartych Zobacz s, można ozdobić metody wysyłają klasy widoku, podobnie jak to:

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): 
    ... 
Powiązane problemy