DRF的版本
版本控制是做什么用的, 我們為什么要用
首先我們要知道我們的版本是干嘛用的呢~~大家都知道我們開發項目是有多個版本的~~
隨着我們項目的更新~版本就越來越多~~我們不可能新的版本出了~以前舊的版本就不進行維護了~~~
那我們就需要對版本進行控制~~這個DRF也給我們提供了一些封裝好的版本控制方法~~
版本控制怎么用
之前我們學視圖的時候知道APIView,也知道APIView返回View中的view函數,然后調用的dispatch方法~
那我們現在看下dispatch方法~~看下它都做了什么~~

執行self.initial方法之前是各種賦值,包括request的重新封裝賦值,下面是路由的分發,那我們看下這個方法都做了什么~~

我們可以看到,我們的version版本信息賦值給了 request.version 版本控制方案賦值給了 request.versioning_scheme~~
其實這個版本控制方案~就是我們配置的版本控制的類~~
也就是說,APIView通過這個方法初始化自己提供的組件~~
我們接下來看看框架提供了哪些版本的控制方法~~在rest_framework.versioning里~~

框架一共給我們提供了這幾個版本控制的方法~~我們在這里只演示一個~~因為基本配置都是一樣的~~
詳細用法
我們看下放在URL上攜帶版本信息怎么配置~~
REST_FRAMEWORK = { # 默認使用的版本控制類 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # 允許的版本 'ALLOWED_VERSIONS': ['v1', 'v2'], # 版本使用的參數名稱 'VERSION_PARAM': 'version', # 默認使用的版本 'DEFAULT_VERSION': 'v1', }
urlpatterns = [ url(r"^versions", MyView.as_view()), url(r"^(?P<version>[v1|v2]+)/test01", TestView.as_view()), ]
class TestView(APIView): def get(self, request, *args, **kwargs): print(request.versioning_scheme) ret = request.version if ret == "v1": return Response("版本v1的信息") elif ret == "v2": return Response("版本v2的信息") else: return Response("根本就匹配不到這個路由")
其他的版本控制的類,配置方法都差不多~~這里就不一一例舉了~~
DRF的認證
認證是干嘛的呢~
我們都知道~我們可以在網站上登錄~然后可以有個人中心,對自己信息就行修改~~~
但是我們每次給服務器發請求,由於Http的無狀態,導致我們每次都是新的請求~~
那么服務端需要對每次來的請求進行認證,看用戶是否登錄,以及登錄用戶是誰~~
那么我們服務器對每個請求進行認證的時候,不可能在每個視圖函數中都寫認證~~~
一定是把認證邏輯抽離出來~~以前我們可能會加裝飾器~或者中間件~~那我們看看DRF框架給我們提供了什么~~~
認證怎么用
上面講版本的時候我們知道~在dispatch方法里~執行了initial方法~~那里初始化了我們的版本~~
如果我們細心我們能看到~版本的下面其實就是我們的認證,權限,頻率組件了~~
我們先看看我們的認證組件~~

我們進去我們的認證看下~~

我們這個權限組件返回的是request.user,那我們這里的request是新的還是舊的呢~~
我們的initial是在我們request重新賦值之后的~所以這里的request是新的~也就是Request類實例對象~~
那這個user一定是一個靜態方法~我們進去看看~~


我沒在這里反復的截圖跳轉頁面~~大家可以嘗試着自己去找~~要耐心~~細心~~
我們通過上面基本可以知道我們的認證類一定要實現的方法~~以及返回值類型~~以及配置的參數authentication_classes~
下面我們來看看具體用法~~~
認證的詳細用法
我們先寫個認證的小demo~~我們先建一個用戶表~字段為用戶名以及對應的token值~~
# 先在model中注冊模型類 # 並且進行數據遷移 # 測試我就簡寫了~ class UserInfo(models.Model): username = models.CharField(max_length=32) token = models.UUIDField()
# 寫視圖類並且用post請求注冊一個用戶 class UserView(APIView): def post(self, request, *args, **kwargs): username = request.data["username"] UserInfo.objects.create(username=username, token=uuid.uuid4()) return Response("注冊成功")
准備工作完成~我們來開始我們的認證~~
# 注意我們這個認證的類必須實現的方法以及返回值 class MyAuth(BaseAuthentication): def authenticate(self, request): request_token = request.query_params.get("token", None) if not request_token: raise AuthenticationFailed({"code": 1001, "error": "缺少token"}) token_obj = UserInfo.objects.filter(token=request_token).first() if not token_obj: raise AuthenticationFailed({"code": 1001, "error": "無效的token"}) return token_obj.username, token_obj
class TestAuthView(APIView): authentication_classes = [MyAuth, ] def get(self, request, *args, **kwargs): return Response("測試認證")
REST_FRAMEWORK = { # 默認使用的版本控制類 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # 允許的版本 'ALLOWED_VERSIONS': ['v1', 'v2'], # 版本使用的參數名稱 'VERSION_PARAM': 'version', # 默認使用的版本 'DEFAULT_VERSION': 'v1', # 配置全局認證 'DEFAULT_AUTHENTICATION_CLASSES': ["BRQP.utils.MyAuth", ] }
