在CreateView中使用Django的permission_required装饰器和method_decorator来获取get_success_url(self)。

4
    from django.contrib.auth.decorators import permission_required  
    from django.utils.decorators import method_decorator  
    class EnvCreate(CreateView):

           model = Capacity.models.Env
           fields = ["name","dns","manager"]
           template_name_suffix = '_create_form'

           @method_decorator(permission_required('Capacity.add_env'))
           def get_success_url(self):
                  return reverse("envapps", kwargs={"envid": self.object.pk})

我希望允许用户添加“env”的权限只有在他拥有相应的许可权限时才能做到。
我已经阅读了许多消息和博客,发现实现该功能的方法如上所述。
但是,在调用get_success_url之前我想使用dispatch()方法(不确定是否存在问题),而在这些消息和博客中它们都是在调用dispatch()方法后使用的。
当我尝试由拥有许可权限的用户创建“env”时,我收到以下错误信息:
    TypeError at /Capacity/create/
    _wrapped_view() takes at least 1 argument (0 given)
    Request Method: POST
    Request URL:    http://172.16.68.20:7000/Capacity/create/
    Django Version: 1.6.1
    Exception Type: TypeError
    Exception Value: _wrapped_view() takes at least 1 argument (0 given)
    Exception Location: /usr/lib/python2.6/site-packages/django/utils/decorators.py in _wrapper, line 29

有什么想法,我在做错了什么或者有什么解决方法吗?
2个回答

7

我明白了,我在使用 dispatch 时理解有误。

    from django.contrib.auth.decorators import permission_required
    from django.utils.decorators import method_decorator
    class EnvCreate(CreateView):

       model = Capacity.models.Env
       fields = ['name','dns','manager']
       template_name_suffix = '_create_form'

       @method_decorator(permission_required('Capacity.add_env',raise_exception=True))
       def dispatch(self, request):
            return super(EnvCreate, self).dispatch(request)

       def get_success_url(self):
            return reverse('envapps', kwargs={'envid': self.object.pk})

0

类视图方法不能像这样装饰: https://docs.djangoproject.com/en/1.6/topics/class-based-views/intro/#decorating-the-class 你应该研究一下 Mixins,这将是实现此功能的最佳方法。 您可以通过检查 Django Braces 轻松查看(甚至可能重用)此类功能: https://github.com/brack3t/django-braces

此外,为什么要在 get_success_url 方法中实现此功能?如果用户无权执行操作,则应在任何数据提交之前拒绝他,这更安全,在流量和操作方面具有较少的系统负载。 如果您仍然需要执行此任务,请创建一个 Mixin,在 get_success_url 中检查权限,如果用户具有权限,则正常进行,如果没有,则抛出异常。请注意,get_success_url 在表单成功验证后调用,这意味着您的数据已经保存,如果需要除登录或权限检查之外的其他检查,则应在 form_valid 方法中进行。


已经找到解决方案。我不需要在get_success_url之前添加装饰器,只需按照您提供的链接中所示添加一个dispatch函数即可。因此,我保留了原来的get_success_url函数,并在新的dispatch函数之前添加了@method_decorator(permission...)。感谢您的帮助。 - Ashwin Sethi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接