How to use the user_passes_test decorator in class based views?

I am trying to check certain conditions before a user is allowed to view a specific user's settings page. I am trying to achieve this using the user_passes_test decorator. The function is in the class-based view as follows. I use the method decorator to decorate the get_initial function in the view.

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

The following is the test_settings function:

 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 

I get an error below with a decorator.

 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) 

I am not sure how to solve this error. Am I applying a decorator to the wrong function? Any links would be helpful.

+6
source share
1 answer

Django 1.9 has authentication mixins for class based views. You can use UserPassesTest mixin as follows.

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

Please note that in this case you need to override get_login_url because you want to redirect to a different URL depending on whether the user is not logged in or not logged in, but failed the test.

For Django 1.8 and earlier, you should decorate the dispatch method, not 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) 
+14
source

Source: https://habr.com/ru/post/985295/


All Articles