django类需要装饰器

我在理解新的CBV如何工作方面遇到了一些麻烦。 我的问题是,我需要在所有视图中登录,并在其中一些视图中指定特定的权限。 在基于函数的视图中,我使用@permission_required()和视图中的login_required属性来实现,但我不知道如何在新视图上执行此操作。 django文档中是否有解释这一点的内容? 我没有找到任何东西。 我的代码有什么问题?

我尝试使用@method_decorator,但它回复“ /空格/ prueba / _wrapped_view()至少需要1个参数(0给出)TypeError

这里是代码(GPL):

from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required, permission_required

class ViewSpaceIndex(DetailView):

    """
    Show the index page of a space. Get various extra contexts to get the
    information for that space.

    The get_object method searches in the user 'spaces' field if the current
    space is allowed, if not, he is redirected to a 'nor allowed' page. 
    """
    context_object_name = 'get_place'
    template_name = 'spaces/space_index.html'

    @method_decorator(login_required)
    def get_object(self):
        space_name = self.kwargs['space_name']

        for i in self.request.user.profile.spaces.all():
            if i.url == space_name:
                return get_object_or_404(Space, url = space_name)

        self.template_name = 'not_allowed.html'
        return get_object_or_404(Space, url = space_name)

    # Get extra context data
    def get_context_data(self, **kwargs):
        context = super(ViewSpaceIndex, self).get_context_data(**kwargs)
        place = get_object_or_404(Space, url=self.kwargs['space_name'])
        context['entities'] = Entity.objects.filter(space=place.id)
        context['documents'] = Document.objects.filter(space=place.id)
        context['proposals'] = Proposal.objects.filter(space=place.id).order_by('-pub_date')
        context['publication'] = Post.objects.filter(post_space=place.id).order_by('-post_pubdate')
        return context

CBV文档中列出了一些策略:

  • 在你的urls.py路由中添加修饰器,例如login_required(ViewSpaceIndex.as_view(..))

  • 用一个method_decorator装饰你的CBV的dispatch方法,例如,

    from django.utils.decorators import method_decorator
    
    @method_decorator(login_required, name='dispatch')
    class ViewSpaceIndex(TemplateView):
        template_name = 'secret.html'
    

    在Django 1.9之前,你不能在类上使用method_decorator ,所以你必须重载dispatch方法:

    class ViewSpaceIndex(TemplateView):
    
        @method_decorator(login_required)
        def dispatch(self, *args, **kwargs):
            return super(ViewSpaceIndex, self).dispatch(*args, **kwargs)
    
  • 使用像Django 1.9+中提供的django.contrib.auth.mixins.LoginRequiredMixin这样的访问组合,并在其他答案中详细介绍:

    from django.contrib.auth.mixins import LoginRequiredMixin
    
    class MyView(LoginRequiredMixin, View):
    
        login_url = '/login/'
        redirect_field_name = 'redirect_to'
    
  • 文档中解释了您得到TypeError的原因:

    注意:method_decorator将* args和** kwargs作为参数传递给类上的装饰方法。 如果你的方法不接受一组兼容的参数,它会引发一个TypeError异常。


    这是我的方法,我创建了一个受保护的mixin(这保存在我的mixin库中):

    from django.contrib.auth.decorators import login_required
    from django.utils.decorators import method_decorator
    
    class LoginRequiredMixin(object):
        @method_decorator(login_required)
        def dispatch(self, request, *args, **kwargs):
            return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
    

    每当你想要一个视图被保护,你只需添加适当的mixin:

    class SomeProtectedViewView(LoginRequiredMixin, TemplateView):
        template_name = 'index.html'
    

    只要确保你的mixin是第一个。

    更新:我在2011年发布了这个版本,从版本1.9开始,Django现在包含这个和其他有用的混合(AccessMixin,PermissionRequiredMixin,UserPassesTestMixin)作为标准!


    以下是使用基于类的装饰器的替代方法:

    from django.utils.decorators import method_decorator
    
    def class_view_decorator(function_decorator):
        """Convert a function based decorator into a class based decorator usable
        on class based Views.
    
        Can't subclass the `View` as it breaks inheritance (super in particular),
        so we monkey-patch instead.
        """
    
        def simple_decorator(View):
            View.dispatch = method_decorator(function_decorator)(View.dispatch)
            return View
    
        return simple_decorator
    

    这可以像这样简单地使用:

    @class_view_decorator(login_required)
    class MyView(View):
        # this view now decorated
    
    链接地址: http://www.djcxy.com/p/77259.html

    上一篇: required decorators on django class

    下一篇: How to log exception details in Spring AOP with try with empty catch block?