開發項目是有多個版本的數據庫
隨着項目的更新,版本就愈來愈多.不可能新的版本出了,之前舊的版本就不進行維護了服務器
那咱們就須要對版本進行控制,這個DRF框架也給咱們提供了一些封裝好的版本控制方法框架
流程ide
ViewClass.as_view –> APIView.as_view –> View.as_view –> return self.dispatch –> 找 API.dispatch() –> initial(): version, scheme = self.determine_version(request, *args, **kwargs)函數
APIView返回View中的view函數,而後調用的dispatch方法,那咱們如今看下dispatch方法,看下它都作了什麼post
執行self.initial方法以前是各類賦值,包括request的從新封裝賦值,下面是路由的分發,那咱們看下這個方法都作了什麼測試
咱們能夠看到,咱們的version版本信息賦值給了 request.version 版本控制方案賦值給了 request.versioning_scheme~~網站
其實這個版本控制方案~就是咱們配置的版本控制的類ui
也就是說,APIView經過這個方法初始化本身提供的組件url
咱們接下來看看框架提供了哪些版本的控制方法~~在rest_framework.versioning裏~~
REST_FRAMEWORK 的設置都在一個字典裏面 rest_framework 視圖APIView的as_view 方法對View中的request 進行了封裝
版本控制代碼的實現
版本配置 DRFDemo/settings.py
REST_FRAMEWORK = { # 默認使用的版本控制類 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # 容許的版本 'ALLOWED_VERSIONS': ['v1', 'v2'], # 版本使用的參數名稱 'VERSION_PARAM': 'version', # 默認使用的版本 'DEFAULT_VERSION': 'v1', }
REST_FRAMEWORK = { # "DEFAULT_VERSIONING_CLASS": "utils.version.MyVersion", # 自定義的版本控制類 "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.QueryParameterVersioning", "DEFAULT_VERSION": "v1", "ALLOWED_VERSIONS": "v1, v2", "VERSION_PARAM": "ver" # ver=v1 }
自定義版本控制類 utils/version.py
from rest_framework import versioning class MyVersion(object): def determine_version(self, request, *args, **kwargs): # 返回值 給了request.version # 返回版本號 # 版本號攜帶在過濾條件 xxxx?version=v1 version = request.query_params.get("version", "v1") return version
urlpatterns = [ path(r"v1/", DemoView.as_view()), ]
視圖 versionDemo/views.py
from rest_framework.views import APIView from rest_framework.response import Response class DemoView(APIView): def get(self, request): print(request.version) print(request.versioning_scheme) # 獲得版本號 根據版本號的不一樣返回不一樣的信息 if request.version == "v1": return Response("v1版本的數據") elif request.version == "v2": return Response("v2版本的數據") return Response("不存在的版本")
咱們都知道,咱們能夠在網站上登陸~而後能夠有我的中心,對本身信息就行修改 可是咱們每次給服務器發請求,因爲Http的無狀態,致使咱們每次都是新的請求 那麼服務端須要對每次來的請求進行認證,看用戶是否登陸,以及登陸用戶是誰 那麼咱們服務器對每一個請求進行認證的時候,不可能在每一個視圖函數中都寫認證 必定是把認證邏輯抽離出來~~之前咱們可能會加裝飾器~或者中間件~~那咱們看看DRF框架給咱們提供了什麼
請求進來的流程
Viewclass.as_view –> APIView.as_view –> View.as_view –> return self.dispatch –> API.dispatch() -> self.initial(request, *args, **kwargs) 初始化包裝view的request
在dispatch方法裏~執行了initial方法~~那裏初始化了咱們的版本
版本的下面其實就是咱們的認證,權限,頻率組件了先看看認證組件
咱們這個權限組件返回的是request.user,那咱們這裏的request是新的仍是舊的呢~~
咱們的initial是在咱們request從新賦值以後的~因此這裏的request是新的~也就是Request類實例對象~~
那這個user必定是一個靜態方法~咱們進去看看
寫一個認證的類
from rest_framework.exceptions import AuthenticationFailed from authDemo.models import User from rest_framework.authentication import BaseAuthentication class MyAuth(BaseAuthentication): def authenticate(self, request): # 作認證 看他是否登陸 # 從url過濾條件裏拿到token # 去數據庫看token是否合法 # 合法的token可以獲取用戶信息 token = request.query_params.get("token", "") if not token: raise AuthenticationFailed("沒有攜帶token") user_obj = User.objects.filter(token=token).first() if not user_obj: raise AuthenticationFailed("token不合法") # return (None, None) return (user_obj, token)
配置全局認證
REST_FRAMEWORK = { # "DEFAULT_VERSIONING_CLASS": "utils.version.MyVersion", "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.QueryParameterVersioning", "DEFAULT_VERSION": "v1", "ALLOWED_VERSIONS": "v1, v2", "VERSION_PARAM": "ver", # "DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.MyAuth", ] # 這裏寫的是全局認證了 }
import uuid from .models import User from utils.auth import MyAuth from rest_framework.views import APIView from rest_framework.response import Response class DemoView(APIView): def get(self, request): return Response("認證demo~") class LoginView(APIView): def post(self, request): username = request.data.get("username") pwd = request.data.get("pwd") # 登陸成功 生成token 會把token給你返回 token = uuid.uuid4() User.objects.create(username=username, pwd=pwd, token=token) return Response("建立用戶成功") class TestView(APIView): authentication_classes = [MyAuth, ] # 局部視圖認證 def get(self, request): print(request.user) print(request.auth) user_id = request.user.id return Response("認證測試")
5