五、REST framework:版本控制

1、概述、

restful规范中,api需要体现版本信息,DRF针对于版本控制也有自己的一套逻辑

2、通过GET参数传递版本信息 QueryParameterVersioning

# 导入版本控制类QueryParameterVersioning,该类通过url的get中获取版本信息
from rest_framework.versioning import QueryParameterVersioning


class LoginView(MyAPIView):

    # authentication_classes 为认证类的默认配置参数,必须怎么写,详细过程可以查看源码
    # 当不使用认证类时,列表为空
    # 请注意,当类中使用authentication_classes=[认证类1, 认证类2, ...]时,认证默认使用就近原则,使用类中的authentication_classes
    authentication_classes = [QueryParamsAuthentication]  # 通过url认证
    # 请注意,当类中使用permission_classes=[权限类1, 权限类2, ...]时,权限默认使用就近原则,使用类中的permission_classes
    permission_classes = [MyPermission1, MyPermission2]  # role=1和2的的权限
    # 应用限流类,throttle_classes限流类的默认配置参数,必须怎么写,详细过程可以查看源码
    throttle_classes = [MyThrottle]
    # versioning_class 为版本的默认配置参数,必须怎么写,详细过程可以查看源码
    versioning_class = QueryParameterVersioning

    def get(self, request, *args, **kwargs):
        # 当使用QueryParameterVersioning时,此类会拿到请求中的version并对request.version进行赋值
        # 需要注意的是:默认情况下 version 是默认写法,不能是其他的
        print("request.version:", request.version)
        return Response('GET')

访问接口

控制台输出

2.1、配置版本信息

2.2、通过QueryParameterVersioning源码,可以看到内部使用了version_param和default_version两个变量,这两个变量位于父类 BaseVersioning中,而且还调用了 is_allowed_version父类的方法,此方法使用了一个allowed_versions变量,三个变量的默认配置为:

    default_version = api_settings.DEFAULT_VERSION
    allowed_versions = api_settings.ALLOWED_VERSIONS
    version_param = api_settings.VERSION_PARAM

2.3、那么我们可以通过settings配置相关信息

REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    # 添加DEFAULT_PERMISSION_CLASSES使其支持全局认证
    "DEFAULT_AUTHENTICATION_CLASSES": ["auto_project.ext.myAuthentication.QueryParamsAuthentication",
                                       "auto_project.ext.myAuthentication.HeaderAuthentication",
                                       "auto_project.ext.myAuthentication.BodyAuthentication",
                                       "auto_project.ext.myAuthentication.NoAuthentication",
                                       ],
    # 添加DEFAULT_PERMISSION_CLASSES,所有视图默认全部应用权限
    "DEFAULT_PERMISSION_CLASSES": ["auto_project.ext.MyPermission.MyPermission1"],
    # 添加限流配置
    "DEFAULT_THROTTLE_RATES": {"xxx": "5/m", "yyy": "10/m"},
    # 版本控制
    # VERSION_PARAM配置版本参数名称,接口请求时,url连接中必须叫 version 否则 request.version接收不到版本信息
    # 如:http://127.0.0.1:8000/api/v5/LoginView/?xx=v11 当为xx时,request.version接收到的信息为 None
    "VERSION_PARAM": "version",
    # 默认版本,当什么都没有传递时,request.version的默认值
    "DEFAULT_VERSION": "v1",
    # 允许的版本集合,当版本信息不包含在此集合中时,触发版本错误异常
    "ALLOWED_VERSIONS": ["v1", "v2"],
    "NON_FIELD_ERRORS_KEY": "全局验证"  # 可以先了解,后面会说用法
}
# 请注意:验证 VERSION_PARAM时,最好注释掉其它两个配置进行验证

 3、通过url路由参数传递版本信息 QueryParameterVersioning

# 导入版本控制类QueryParameterVersioning,该类通过url的get中获取版本信息
# from rest_framework.versioning import QueryParameterVersioning
# 导入版本控制类URLPathVersioning,该类通过url路由获取版本信息
from rest_framework.versioning import URLPathVersioning


class LoginView(MyAPIView):

    # authentication_classes 为认证类的默认配置参数,必须怎么写,详细过程可以查看源码
    # 当不使用认证类时,列表为空
    # 请注意,当类中使用authentication_classes=[认证类1, 认证类2, ...]时,认证默认使用就近原则,使用类中的authentication_classes
    authentication_classes = [QueryParamsAuthentication]  # 通过url认证
    # 请注意,当类中使用permission_classes=[权限类1, 权限类2, ...]时,权限默认使用就近原则,使用类中的permission_classes
    permission_classes = [MyPermission1, MyPermission2]  # role=1和2的的权限
    # 应用限流类,throttle_classes限流类的默认配置参数,必须怎么写,详细过程可以查看源码
    throttle_classes = [MyThrottle]
    # versioning_class 为版本的默认配置参数,必须怎么写,详细过程可以查看源码
    versioning_class = URLPathVersioning

    def get(self, request, *args, **kwargs):
        # 当使用URLPathVersioning时,此类会拿到url路由中的的version信息并对request.version进行赋值
        # 需要注意的是:默认情况下 version 是默认写法,不能是其他的
        print("request.version:", request.version)
        return Response('GET')

3.1、路由配置

urlpatterns = [
    # <str:version> 表示捕获url该部分的信息,并赋值给version,并且这个变量在视图函数中可以通过version这个名称来访问
    # 当然在请求中可以获取到version,但是会导致后续很多复杂逻辑,不建议怎么做
    # URLPathVersioning会对version进行处理,可以避免其他逻辑性问题
    path('api/<str:version>/LoginAPIView/', views.LoginAPIView.as_view()),

4、版本也支持进行全局配置

REST_FRAMEWORK = {
    "UNAUTHENTICATED_USER": None,
    # 添加DEFAULT_PERMISSION_CLASSES使其支持全局认证
    "DEFAULT_AUTHENTICATION_CLASSES": ["auto_project.ext.myAuthentication.QueryParamsAuthentication",
                                       "auto_project.ext.myAuthentication.HeaderAuthentication",
                                       "auto_project.ext.myAuthentication.BodyAuthentication",
                                       "auto_project.ext.myAuthentication.NoAuthentication",
                                       ],
    # 添加DEFAULT_PERMISSION_CLASSES,所有视图默认全部应用权限
    "DEFAULT_PERMISSION_CLASSES": ["auto_project.ext.MyPermission.MyPermission1"],
    # 添加限流配置
    "DEFAULT_THROTTLE_RATES": {"xxx": "5/m", "yyy": "10/m"},
    # 版本控制
    # VERSION_PARAM默认配置,接口请求时,url连接中必须叫 version 否则 request.version接收不到版本信息
    # 如:http://127.0.0.1:8000/api/v5/LoginView/?xx=v11 当为xx时,request.version接收到的信息为 None
    "VERSION_PARAM": "version",
    # 默认版本,当什么都没有传递时,request.version的默认值
    "DEFAULT_VERSION": "v1",
    # 允许的版本集合,当版本信息不包含在此集合中时,触发版本错误异常
    "ALLOWED_VERSIONS": ["v1", "v2"],
    # 配置版本类,使用DRF自己的URLPathVersioning
    "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",
    "NON_FIELD_ERRORS_KEY": "全局验证"  # 可以先了解,后面会说用法
}

配置完成后,可以删除视图函数中的 versioning_class = URLPathVersioning 配置信息,接口正常访问。

5、除了这两种控制版本的信息还支持通过header头部信息进行版本控制,用法大致相同,这里不在演示。

header类:

from rest_framework.versioning import AcceptHeaderVersioning

 

posted @ 2024-12-30 17:44  蜗牛·哥  阅读(11)  评论(0)    收藏  举报