許可權控制是如何實現的? 一般來說,先有認證才有許可權,也就是用戶登錄後才能判斷其許可權,未登錄用戶給他一個預設許可權。 Django接收到一個請求,首先經過許可權的檢查,如果通過檢查,擁有訪問的許可權,則予以放行,進入到視圖處理。如果沒有通過檢查,不會進入視圖層,直接返回前端相應信息。 使用許可權控制 許可權控制 ...
許可權控制是如何實現的?
一般來說,先有認證才有許可權,也就是用戶登錄後才能判斷其許可權,未登錄用戶給他一個預設許可權。
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句中的代碼,來拋出異常。