python - 如何在基于类的 View 中使用 user_passes_test 装饰器?

标签 python django python-2.7 decorator python-decorators

我试图在允许用户查看特定用户设置页面之前检查某些条件。我正在尝试使用 user_passes_test 装饰器来实现这一点。该函数位于基于类的 View 中,如下所示。我正在使用方法装饰器来装饰 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 { ..........
       ...... .... 

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

我不确定如何解决这个错误。我是否在错误的函数上应用了装饰器?任何线索都会有所帮助。

最佳答案

Django 1.9 具有用于基于类的 View 的身份验证混合。您可以使用 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)

关于python - 如何在基于类的 View 中使用 user_passes_test 装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29682704/

相关文章:

python - 使用分割字符串的长度创建符号数组

python - ImportError at/No module named urls

python - 如何在 PySpark 中读取 Avro 文件

python - 在 2d python 列表中附加值

python - 知道为什么我会收到此错误吗?

python - 使用 session 的Django View 中 “def”的语法错误

python - 如何在 Python 中使用 Beautifulsoup 查找 div 内的所有 anchor 标签

c++ - tensorflow:无效的 fastbin 条目(免费):0x00007f2fa8023940

Python、Django - 在 settings.py 中访问环境变量

javascript - Django - 将变量传递给同一脚本标签内的javascript文件