drf5 版本和认证组件
开发项目是有多个版本的
随着项目的更新,版本就越来越多.不可能新的版本出了,以前旧的版本就不进行维护了
那我们就需要对版本进行控制,这个DRF框架也给我们提供了一些封装好的版本控制方法
版本控制组件
流程
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方法,看下它都做了什么
执行self.initial方法之前是各种赋值,包括request的重新封装赋值,下面是路由的分发,那我们看下这个方法都做了什么
我们可以看到,我们的version版本信息赋值给了 request.version 版本控制方案赋值给了 request.versioning_scheme~~
其实这个版本控制方案~就是我们配置的版本控制的类
也就是说,APIView通过这个方法初始化自己提供的组件
我们接下来看看框架提供了哪些版本的控制方法~~在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