2015-04-16 16 views
6

Sto provando a verificare determinate condizioni prima che l'utente possa vedere una particolare pagina delle impostazioni utente. Sto cercando di raggiungere questo obiettivo utilizzando il decoratore user_passes_test. La funzione si trova in una vista basata sulla classe come segue. Sto usando il decoratore di metodi per decorare la funzione get_initial nella vista.Come utilizzare il decoratore user_passes_test nelle viste basate sulle classi?

class UserSettingsView(LoginRequiredMixin, FormView): 
    success_url = '.' 
    template_name = 'accts/usersettings.html' 

    def get_form_class(self): 
     if self.request.user.profile.is_student: 
      return form1 
     if self.request.user.profile.is_teacher: 
      return form2 
     if self.request.user.profile.is_parent: 
      return form3 

    @method_decorator(user_passes_test(test_settings, login_url='/accounts/usertype/')) 
    def get_initial(self): 
     if self.request.user.is_authenticated(): 
      user_obj = get_user_model().objects.get(email=self.request.user.email) 
      if user_obj.profile.is_student: 
       return { .......... 
     ...... .... 

Di seguito è la funzione test_settings:

def test_settings(user): 
    print "I am in test settings" 
    if not (user.profile.is_student or user.profile.is_parent or user.profile.is_teacher): 
     return False 
    else: 
     return True 

sto ottenendo l'errore sotto con il decoratore.

File "../django/core/handlers/base.py", line 111, in get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
File "../django/views/generic/base.py", line 69, in view 
    return self.dispatch(request, *args, **kwargs) 
File "../braces/views.py", line 107, in dispatch 
    request, *args, **kwargs) 
File "../django/views/generic/base.py", line 87, in dispatch 
    return handler(request, *args, **kwargs) 
File "../django/views/generic/edit.py", line 162, in get 
    form = self.get_form(form_class) 
File "../django/views/generic/edit.py", line 45, in get_form 
    return form_class(**self.get_form_kwargs()) 
File "../django/views/generic/edit.py", line 52, in get_form_kwargs 
    'initial': self.get_initial(), 
File "../django/utils/decorators.py", line 29, in _wrapper 
    return bound_func(*args, **kwargs) 
TypeError: _wrapped_view() takes at least 1 argument (0 given) 

Non so come risolvere questo errore. Sto applicando il decoratore sulla funzione sbagliata? Qualsiasi porta sarà utile.

risposta

14

Django 1.9 dispone di mix di autenticazione per viste basate su classi. È possibile utilizzare il mixin UserPassesTest come segue.

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin 

class UserSettingsView(LoginRequiredMixin, UserPassesTestMixin, View): 
    def test_func(self): 
     return test_settings(self.request.user) 

    def get_login_url(self): 
     if not self.request.user.is_authenticated(): 
      return super(UserSettingsView, self).get_login_url() 
     else: 
      return '/accounts/usertype/' 

Si noti che in questo caso è necessario eseguire l'override get_login_url, perché si vuole reindirizzare a un URL diverso a seconda che l'utente non è connesso, o è connesso, ma non supera il test.

Per Django 1.8 e versioni precedenti, è necessario decorare il metodo dispatch, non get_initial.

@method_decorator(user_passes_test(test_settings, login_url='/accounts/usertype/')) 
def dispatch(self, *args, **kwargs): 
    return super(UserSettingsView, self).dispatch(*args, **kwargs) 
+0

Capito. Grazie! – pxUx

+0

L'esempio indica che se l'utente è autenticato, restituisce l'URL di accesso. Dovrebbe essere scambiato il se/else? – pymarco

+0

@pymarco buon punto, risolto ora – Alasdair

Problemi correlati