一尘不染

如何在基于Django类的视图上使用Permission_required装饰器

django

我在理解新CBV的工作方式时遇到了一些麻烦。我的问题是,我需要在所有视图中登录,在某些视图中需要特定的权限。在基于函数的视图中,我使用@permission_required()和视图中的login_required属性来执行此操作,但是我不知道如何在新视图上执行此操作。django文档中是否有某些部分对此进行了解释?我什么都没找到 我的代码有什么问题?

我尝试使用@method_decorator,但它回答“ / spaces / prueba / _wrapped_view()处的TypeError至少接受1个参数(给定0) ”

这是代码(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

阅读 1315

收藏
2020-03-26

共1个答案

一尘不染

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

  1. 在你的urls.py路线中添加装饰器,例如,login_required(ViewSpaceIndex.as_view(..))

  2. dispatch用以下方法装饰你的CBV 方法method_decorator

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文档中解释了你获得a的原因:

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

2020-03-26