drf5 版本和認證組件

開發項目是有多個版本的數據庫

隨着項目的更新,版本就愈來愈多.不可能新的版本出了,之前舊的版本就不進行維護了服務器

那咱們就須要對版本進行控制,這個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',
}

第一步 setting.py
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()),
]
第二步 urls.py

視圖 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)
utils/auth.py

配置全局認證

 
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("認證測試")

視圖級別認證 authDemo/views.py

5

相關文章
相關標籤/搜索