1. 程式人生 > >Django REST Framework之許可權元件

Django REST Framework之許可權元件

許可權控制是如何實現的?

一般來說,先有認證才有許可權,也就是使用者登入後才能判斷其許可權,未登入使用者給他一個預設許可權。

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 = []”,即可

原始碼分析

其實許可權的原始碼流程跟認證的流程基本相同。還是要抓住通過原始碼要想知道什麼,不然就會陷入浩如煙海的原始碼之中。

1.為什麼會使用permission_classes屬性變數?

python 的面向物件程式設計中,我們首先要執行的方法肯定是dispatch方法,所以我們的分析入口就是dispatch方法,在dispatch方法中,可以看到,通過initialize_request方法將django原生的request進行了一次封裝。由initialize_request方法的實現過程可以看出,將其封裝例項化成了一個Request物件。但許可權判斷並沒有像認證一樣初始化到了Request物件中,但對django原生的request封裝還是需要強調的,因為編寫程式碼的過程中對django原生的request的使用是必不可免的。

同樣的,許可權判斷的具體過程跟認證一樣,也是在dispatch方法中所呼叫的initial方法中實現。再跳轉到initial方法中去。

在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句中的程式碼,來丟擲異常。

&n