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

相关文章
相关标签/搜索