2015-04-16 83 views
6

我想在用戶被允許查看特定用戶設置頁面之前檢查某些條件。我正在嘗試使用user_passes_test修飾器實現此目的。該函數位於基於類的視圖中,如下所示。我正在使用方法裝飾器來裝飾視圖中的get_initial函數。如何在基於類的視圖中使用user_passes_test裝飾器?

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 { .......... 
     ...... .... 

下面是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 

我提示以下錯誤:與裝飾。

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) 

我不知道如何解決此錯誤。我是否將裝飾器應用於錯誤的功能?任何線索都會有所幫助。

回答

14

Django 1.9具有基於類的視圖的認證mixins。您可以按照以下方式使用mixin UserPassesTest

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/' 

注意,在這種情況下,你必須重寫get_login_url,因爲你要重定向到根據用戶是否沒有登錄或已經登錄,但未能通過測試不同的URL。

對於Django 1.8及更早版本,您應該裝飾dispatch方法,而不是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

明白了。謝謝! – pxUx

+0

您的示例顯示如果用戶已通過身份驗證,則返回登錄URL。 if/else是否應該交換? – pymarco

+0

@pymarco好點,現在修好了 – Alasdair

相關問題