如何在基于 django 类的视图上使用 permission_required 装饰器 [英] How to use permission_required decorators on django class-based views

查看:22
本文介绍了如何在基于 django 类的视图上使用 permission_required 装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having a bit of trouble understanding how the new CBVs work. My question is this, I need to require login in all the views, and in some of them, specific permissions. In function-based views I do that with @permission_required() and the login_required attribute in the view, but I don't know how to do this on the new views. Is there some section in the django docs explaining this? I didn't found anything. What is wrong in my code?

我尝试使用@method_decorator,但它回复TypeError at/spaces/prueba/_wrapped_view() 需要至少 1 个参数(给定 0)"

I tried to use the @method_decorator but it replies "TypeError at /spaces/prueba/ _wrapped_view() takes at least 1 argument (0 given)"

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

urlpatterns = [
    path('view/',login_required(ViewSpaceIndex.as_view(..)),
    ...
]

装饰器是在每个实例的基础上应用的,因此您可以根据需要在不同的 urls.py 路由中添加或删除它.

The decorator is applied on a per-instance basis, so you can add it or remove it in different urls.py routes as needed.

有两种方法可以做到这一点:

There's two ways to do this:

  1. method_decorator 应用于您的 CBV 调度方法,例如,

  1. Apply method_decorator to your CBV dispatch method e.g.,

 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 方法:

If you're using Django < 1.9 (which you shouldn't, it's no longer supported) you can't use method_decorator on the class, so you have to override the dispatch method manually:

    class ViewSpaceIndex(TemplateView):

        @method_decorator(login_required)
        def dispatch(self, *args, **kwargs):
            return super(ViewSpaceIndex, self).dispatch(*args, **kwargs)

  1. 使用像 django.contrib.auth.mixins.LoginRequiredMixin 在这里的其他答案中概述得很好:

  1. Use a mixin like django.contrib.auth.mixins.LoginRequiredMixin outlined well in the other answers here:

 from django.contrib.auth.mixins import LoginRequiredMixin

 class MyView(LoginRequiredMixin, View):

     login_url = '/login/'
     redirect_field_name = 'redirect_to'

确保将 mixin 类放在继承列表的第一位(所以 Python 的 方法解析顺序算法选择正确的东西).

Make sure you place the mixin class first in the inheritance list (so Python's Method Resolution Order algorithm picks the Right Thing).

文档中解释了您收到 TypeError 的原因:

The reason you're getting a TypeError is explained in the docs:

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

Note: method_decorator passes *args and **kwargs as parameters to the decorated method on the class. If your method does not accept a compatible set of parameters it will raise a TypeError exception.

这篇关于如何在基于 django 类的视图上使用 permission_required 装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆