Django REST Framework之权限组件

权限控制是如何实现的?

通常来讲,先有认证才有权限,也就是用户登陆后才能判断其权限,未登陆用户给他一个默认权限。前端

Django接收到一个请求,首先通过权限的检查,若是经过检查,拥有访问的权限,则予以放行,进入到视图处理。若是没有经过检查,不会进入视图层,直接返回前端相应信息。python

使用权限控制

权限控制类:django

class MyPermission(BasePermission):
    message = "您没有权限"

    def has_permission(self, request, view):
        # 判断用户是否有权限,逻辑本身定义。返回值为True或False,表明拥有权限或没有权限
        user_obj = request.user
        if user_obj.type == 3:
            return False
        else:
            return True

views.py:编程

from rest_framework.views import APIView
from utils.permission import MyPermission

class TestView(APIView):
    permission_classes = [MyPermission, ] # 使用该权限控制,能够同时使用多个权限控制类
  
    def get(self, request, *args, **kwargs):
        pass
  
      
     def post(self, request, *args, **kwargs):
        pass
  
        '''
        等等一系列的视图功能方法
        '''

全局权限控制:

settings.py源码分析

REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES" :['utils.permission.Mypermission',]   
}

注意:若是有部分类不须要权限判断的话,能够在Mypermission类中添加“permission_classes = []”,便可post

源码分析

其实权限的源码流程跟认证的流程基本相同。仍是要抓住经过源码要想知道什么,否则就会陷入浩如烟海的源码之中。spa

1.为何会使用permission_classes属性变量?

python 的面向对象编程中,咱们首先要执行的方法确定是dispatch方法,因此咱们的分析入口就是dispatch方法,在dispatch方法中,能够看到,经过initialize_request方法将django原生的request进行了一次封装。由initialize_request方法的实现过程能够看出,将其封装实例化成了一个Request对象。但权限判断并无像认证同样初始化到了Request对象中,但对django原生的request封装仍是须要强调的,由于编写代码的过程当中对django原生的request的使用是必不可免的。3d

一样的,权限判断的具体过程跟认证同样,也是在dispatch方法中所调用的initial方法中实现。再跳转到initial方法中去。rest

在initial方法中,能够看到权限判断的方法,没错,就是经过check_permissions方法实现的。再跳转到这个方法中去。对象

在check_permissions方法中,就能够看到权限的判断就是经过这个for循环实现的。正由于在业务代码中可能存在若干种类型的权限判断,因此才会经过循环去执行咱们定义好的权限判断类来完成多个权限体系的判断功能。这样,咱们能够感受到这里的“self.get_permissions()”的返回值应该就是咱们在视图类中赋值过的permissions_classes属性变量的值。那就跳转到这个方法中去看看吧。

在get_permissions方法中看到,跟认证同样,返回值一样是一个列表生成式,而这个列表生成式使用的属性变量正是咱们赋值过的permission_classes,跟咱们以前的猜想彻底一致。综上所述,咱们为了让drf接口源码使用上咱们本身定义的权限判断类,那咱们就必须按照源码中写的借口,将permission_classes属性变量赋值

2.在权限判断类中为何会定义一个名称为has_permission的方法?

回到check_permissions方法中,咱们看if判断句,前面刚刚说过,在for中的permission其实就是咱们本身定义的权限判断类,那么在if句中的“.has_permission(request,self)”不就应该就是Mypermission类中的方法吗?因此,咱们本身定义的Mypermission类中必定要实现has_permission这个方法。(要注意这个方法的参数)

3.has_permission方法中,为何返回值为布尔值?

仍是跟上一个问题同样的,在上图中的if句中,咱们能够看到“permission.has_permission(request, self)”的返回值不就是布尔值吗,这个返回值不就是has_permission方法返回值吗?当返回值为False时,就会执行if句中的代码,来抛出异常。

相关文章
相关标签/搜索