简体   繁体   English

如何在基于类的视图中使用user_passes_test装饰器?

[英]How to use the user_passes_test decorator in class based views?

I am trying to check certain conditions before the user is allowed to see a particular user settings page. 我试图在允许用户查看特定用户设置页面之前检查某些条件。 I am trying to achieve this using the user_passes_test decorator. 我试图使用user_passes_test装饰器来实现这一点。 The function sits in a class based view as follows. 该函数位于基于类的视图中,如下所示。 I am using method decorator to decorate the get_initial function in the view. 我正在使用方法装饰器来装饰视图中的get_initial函数。

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

Below is the test_settings function: 以下是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

I am getting the below error with the 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 resolve this error. 我不知道如何解决此错误。 Am I applying the decorator on the wrong function? 我在错误的功能上应用装饰器吗? Any leads will be helpful. 任何线索都会有所帮助。

Django 1.9 has authentication mixins for class based views. Django 1.9具有基于类视图的身份验证混合。 You can use the UserPassesTest mixin as follows. 您可以按如下方式使用UserPassesTest mixin。

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

Note that in this case you have to override get_login_url , because you want to redirect to a different url depending on whether the user is not logged in, or is logged in but fails the test. 请注意,在这种情况下,您必须覆盖get_login_url ,因为您要根据用户是否未登录或登录但未通过测试而重定向到其他URL。

For Django 1.8 and earlier, you should decorate the dispatch method, not get_initial . 对于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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM