基本结构
urls.py
from django.conf.urls import url, include
from app import views
urlpatterns = [
url(r'^test/', views.TestView.as_view()),
]
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework import exceptions
class MyPermission(object):
def has_permission(request, self):
'''
权限代码编写区域
'''
return True #权限通过 如果权限不通过 返回False
class TestView(APIView):
permission_classes = [MyPermission, ]
def get(self, request, *args, **kwargs):
pass
def post(self, request, *args, **kwargs):
pass
'''
等等一系列的视图功能方法
'''
注意事项:
1.使用权限类
在需要权限控制的视图类中,写入permission_classes = [MyPermission, ],变量属性permission_classes 是个列表,列表中可写多个权限类,通过权限方才执行视图类的方法。(此方法属于局部的类的权限控制方式)
2.返回值
(1)Ture表示权限通过,False表示权限拒绝
源码分析
(1)寻找函数入口
通过urls.py文件,我们首先要寻找TestView类的as_view()方法,我们能在APIView类找到as_view()方法,APIView继承了View中as_view()方法,返回了一个view函数最终的结果就是调用了dispatch方法,整个视图类的入口就找到了。
(2)为什么要使用permission_classes 属性变量?
现在我们开始寻找dispatch方法,这时候请注意,我们应该从子类TestView中开始寻找这个方法,因为在子类中可能会重构父类的dispatch方法,最后我们在APIView类中找到了dispatch方法。
python 的面向对象编程中,我们首先要执行的方法肯定是dispatch方法,所以我们的分析入口就是dispatch方法,在dispatch方法中,可以看到,通过initialize_request方法将django原生的request进行了一次封装。由initialize_request方法的实现过程可以看出,将其封装实例化成了一个Request对象。但权限判断并没有像认证一样初始化到了Request对象中,但对django原生的request封装还是需要强调的,因为编写代码的过程中对django原生的request的使用是必不可免的。
在check_permissions方法中,就可以看到权限的判断就是通过这个for循环实现的。正因为在业务代码中可能存在若干种类型的权限判断,所以才会通过循环去执行我们定义好的权限判断类来完成多个权限体系的判断功能。这样,我们可以感觉到这里的“self.get_permissions()”的返回值应该就是我们在视图类中赋值过的permissions_classes属性变量的值。那就跳转到这个方法中去看看吧。
在get_permissions方法中看到,跟认证一样,返回值同样是一个列表生成式,而这个列表生成式使用的属性变量正是我们赋值过的permission_classes,跟我们之前的猜测完全一致。综上所述,我们为了让drf接口源码使用上我们自己定义的权限判断类,那我们就必须按照源码中写的借口,将permission_classes属性变量赋值、
(3)为什么要权限控制类中要使用has_permission方法?
回到check_permissions方法中,我们看if判断句,前面刚刚说过,在for中的permission其实就是我们自己定义的权限判断类,那么在if句中的“.has_permission(request,self)”不就应该就是Mypermission类中的方法吗?所以,我们自己定义的Mypermission类中一定要实现has_permission这个方法。(要注意这个方法的参数)
(4)为什么权限控制的返回值为布尔值?
还是跟上一个问题一样的,在上图中的if句中,我们可以看到“permission.has_permission(request, self)”的返回值不就是布尔值吗,这个返回值不就是has_permission方法返回值吗?当返回值为False时,就会执行if句中的代码,来抛出异常。
实例
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]