restful-framwork續集2

1.版本控制

1.1版本控制是做什麼用的, 我們爲什麼要用

首先我們要知道我們的版本是幹嘛用的呢~~大家都知道我們開發項目是有多個版本的~~

隨着我們項目的更新~版本就越來越多~~我們不可能新的版本出了~以前舊的版本就不進行維護了~~~

那我們就需要對版本進行控制~~這個DRF也給我們提供了一些封裝好的版本控制方法~~

1.2版本控制怎麼用

之前我們學視圖的時候知道APIView,也知道APIView返回View中的view函數,然後調用的dispatch方法~

那我們現在看下APIView.dispatch方法~~看下它都做了什麼~~

restful-framwork續集2

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

restful-framwork續集2

我們可以看到,我們的version版本信息賦值給了 request.version  版本控制方案賦值給了 request.versioning_scheme~~

其實這個版本控制方案~就是我們配置的版本控制的類~~

也就是說,APIView通過這個方法初始化自己提供的組件~~

我們接下來看看框架提供了哪些版本的控制方法~~在rest_framework.versioning裏~~

restful-framwork續集2

1.3版本控制的使用

我滴個神,試了其他的試了一個多小時,怎麼弄都不行,我也是沒招了!!稍後處理!!
錯在了一個小點,我滴神,django2.0中是re_path=url,我用了path....
沒看到那個警告信息。。55555555555555555555555555

1.3.1QueryParameterVersioning

settings.py

REST_FRAMEWORK = {
    # 默認使用的版本控制類
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning',
    # 允許的版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    # 版本使用的參數名稱
    'VERSION_PARAM': 'version',
    # 默認使用的版本
    'DEFAULT_VERSION': 'v1',
}
views.py

class DemoView(APIView):
    def get(self, request):
        print("request.version", request.version)
        print("request.versioning_scheme", request.versioning_scheme)
        # 得到版本號  根據版本號的不同返回不同的信息
        if request.version == "v1":
            return Response("v1版本的數據")
        elif request.version == "v2":
            return Response("v2版本的數據")
        return Response("不存在的版本")
urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r"demo", DemoView.as_view()),
]

restful-framwork續集2

1.3.2URLPathVersioning

settings.py

REST_FRAMEWORK = {
    # 默認使用的版本控制類
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    # 允許的版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    # 版本使用的參數名稱
    'VERSION_PARAM': 'version',
    # 默認使用的版本
    'DEFAULT_VERSION': 'v1',
}
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'api/(?P<version>(v1|v2))/demo/', DemoView.as_view(), name='demo'),
]
views.py

class DemoView(APIView):
    def get(self, request, *args, **kwargs):
        print("request.version", request.version)
        print("request.versioning_scheme", request.versioning_scheme)
        # 得到版本號  根據版本號的不同返回不同的信息
        if request.version == "v1":
            return Response("v1版本的數據")
        elif request.version == "v2":
            return Response("v2版本的數據")
        return Response("不存在的版本")

restful-framwork續集2

其他的參考源代碼就可以了,一定注意這個re_path,帶有正則匹配時,使用的是re_path!!!

1.3.3自定義版本類

utils.py

# by gaoxin
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
settings.py

REST_FRAMEWORK = {
    # 默認使用的版本控制類
    'DEFAULT_VERSIONING_CLASS': 'utils.version.MyVersion',

}
views.py

class DemoView(APIView):
    def get(self, request, *args, **kwargs):
        print("request.version", request.version)
        print("request.versioning_scheme", request.versioning_scheme)
        # 得到版本號  根據版本號的不同返回不同的信息
        if request.version == "v1":
            return Response("v1版本的數據")
        elif request.version == "v2":
            return Response("v2版本的數據")
        return Response("不存在的版本")

restful-framwork續集2

2.認證

2.1認證作用

我們都知道~我們可以在網站上登錄~然後可以有個人中心,對自己信息就行修改~~~
但是我們每次給服務器發請求,由於Http的無狀態,導致我們每次都是新的請求~~
那麼服務端需要對每次來的請求進行認證,看用戶是否登錄,以及登錄用戶是誰~~
那麼我們服務器對每個請求進行認證的時候,不可能在每個視圖函數中都寫認證~~~

一定是把認證邏輯抽離出來~~以前我們可能會加裝飾器~或者中間件~~那我們看看DRF框架給我們提供了什麼~~~

2.2認證流程

restful-framwork續集2
restful-framwork續集2
restful-framwork續集2

我們這個權限組件返回的是request.user,那我們這裏的request是新的還是舊的呢~~

我們的initial是在我們request重新賦值之後的~所以這裏的request是新的~也就是Request類實例對象~~

那這個user一定是一個靜態方法~我們進去看看~~

restful-framwork續集2

restful-framwork續集2

2.3認證試驗

models.py

class User(models.Model):

    username = models.CharField(max_length=32)
    pwd = models.CharField(max_length=16)
    token = models.UUIDField()
views.py 

from django.shortcuts import render
import uuid
from app.models import User
from utils.auth import MyAuth
# Create your views here.

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)  # User object (1)
        print(request.auth)  # a890ec1e18c146f2b8542eb465bd6774
        user_id = request.user.id
        return Response("認證測試")
urls.py

from django.contrib import admin
from django.urls import path,include,re_path
from app.views import DemoView,LoginView, TestView
from rest_framework.routers import DefaultRouter
import rest_framework.versioning

router = DefaultRouter()

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'api/demo/', DemoView.as_view(), name='demo'),
re_path(r"login", LoginView.as_view()),
    re_path(r"test", TestView.as_view()),
]
utils/auth.py

# by gaoxin
from rest_framework.exceptions import AuthenticationFailed
from app.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)

restful-framwork續集2
restful-framwork續集2
restful-framwork續集2

2.4配置全局認證

配置在settings.py中

REST_FRAMEWORK = {
    # 默認使用的版本控制類
    'DEFAULT_VERSIONING_CLASS': 'utils.version.MyVersion',
    "DEFAULT_AUTHENTICATION_CLASSES": ["utils.auth.MyAuth", ]

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章