通常來講,先有認證纔有權限,也就是用戶登陸後才能判斷其權限,未登陸用戶給他一個默認權限。前端
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
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屬性變量賦值
回到check_permissions方法中,咱們看if判斷句,前面剛剛說過,在for中的permission其實就是咱們本身定義的權限判斷類,那麼在if句中的「.has_permission(request,self)」不就應該就是Mypermission類中的方法嗎?因此,咱們本身定義的Mypermission類中必定要實現has_permission這個方法。(要注意這個方法的參數)
仍是跟上一個問題同樣的,在上圖中的if句中,咱們能夠看到「permission.has_permission(request, self)」的返回值不就是布爾值嗎,這個返回值不就是has_permission方法返回值嗎?當返回值爲False時,就會執行if句中的代碼,來拋出異常。