浅析Django接口版本控制


Posted in Python onJune 26, 2021

一、前言

RESTful规范中,有关版本的问题,用restful规范做开放接口的时候,用户请求API,系统返回数据。但是难免在系统发展的过程中,不可避免的需要添加新的资源,或者修改现有资源。因此,改动升级必不可少,但是,作为平台开发者,应该知道:一旦API开放出去,有人开始用了,平台的任何改动都需要考虑对当前用户的影响。因此,做开放平台,从第一个API的设计就需要开始API的版本控制策略问题,API的版本控制策略就像是开放平台和平台用户之间的长期协议,其设计的好坏将直接决定用户是否使用该平台,或者说用户在使用之后是否会因为某次版本升级直接弃用该平台。

二、配置

有两种配置方案,一种是在settings中全局配置,第二种是在视图中指定,不过此方法一般不使用,因为版本控制大部分情况下是全局的处理情况

2.1、全局配置

settings.py

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': None,
    'DEFAULT_VERSION': None,
    'ALLOWED_VERSIONS': None,
    'VERSION_PARAM': 'version',
}
  • DEFAULT_VERSIONING_CLASS:指定版本控制的类,譬如:'rest_framework.versioning.NamespaceVersioning',有多种方式。默认为None,为None时,框架变量request.version将始终返回None
  • DEFAULT_VERSION:当版本控制信息不存在时用于设置request.version的默认值,默认设置为None。
  • ALLOWED_VERSIONS:允许的版本号,譬如:['v1', 'v2']。区分大小写,如果请求的版本号不在此列表中,抛出错误,上述的 DEFAULT_VERSION 的值必须是列表中的值,None除外
  • VERSION_PARAM:版本控制参数的字符串,默认就是version,一般不修改

2.2、视图配置

views.py

# 仅仅指定 版本控制类    
class ProfileList(APIView):
    # 指定 版本控制类
    versioning_class = versioning.QueryParameterVersioning

三、drf内置的5个版本控制类

3.1、AcceptHeaderVersioning

基于请求头的版本控制,这种方式也是最推荐的方式

1.http访问方式

GET /bookings/ HTTP/1.1

Host: example.com

Accept: application/json; version=1.0

在上面的示例请求中request.version属性将返回字符串'1.0'。 基于accept headers 的版本控制通常被认为是最佳实践,尽管其他版本控制方式可能适合你的客户端需求。

2.settings

REST_FRAMEWORK = {
	'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning',
        'DEFAULT_VERSION': 'v1',
        'ALLOWED_VERSIONS': ['v1', 'v2'],
}

说明:

  • 设置版本控制类为AcceptHeaderVersioning
  • 没有检测到version时,默认是v1版本
  • 允许的2个版本型号为:['v1', 'v2']

3.serializers

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = BookInfo
        fields = ['title', 'pub_date', 'read', 'comment', 'image']


class BookSerializerV2(serializers.ModelSerializer):
    class Meta:
        model = BookInfo
        fields = ['title', 'pub_date', 'read', 'comment']

说明:

  • 根据不同的版本号,可以对response返回内容进行控制,我们设置2个不同的Book模型的serializer类对应不同的版本
  • 2个序列化类返回的字段不同
  • BookSerializerV2fields中没有包含 image ,那么就应该把属性定义去掉,不然会抛出错误

4.views

class BookView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookSerializer

    def get_serializer_class(self):
        if self.request.version == "v2":
            return BookSerializerV2
        return self.serializer_class

说明:

  • 修改BookView类,重载get_serializer_class方法
  • 通过 self.request.version 获取捕获到的版本号进行控制

5.访问

我们在请求头中添加字段Accept:application/json;version=v1,就会返回BookSerializer的序列化字段,也就是有image字段

浅析Django接口版本控制

我们在请求头中添加字段Accept:application/json;version=v2,就会返回BookSerializerV2的序列化字段,也就是没有image字段

浅析Django接口版本控制

3.2、URLPathVersioning

此方案要求客户端将版本指定为URL路径的一部分。

1.http访问方式

GET /v1/bookings/ HTTP/1.1

Host: example.com

Accept: application/json

说明:

版本控制出现在url路径中,但是具体的这个 v1 出现在哪个部分,取决于url路由配置中的情况

2.settings

REST_FRAMEWORK = {
	'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
        'DEFAULT_VERSION': 'v1',
        'ALLOWED_VERSIONS': ['v1', 'v2'],
}

3.urls

子应用的urls.py中:

urlpatterns = [
    path('<str:version>/books/', views.BookView.as_view()),
]

说明:

设置版本控制在最后,访问url是类似:http://127.0.0.1:8000/api/v2/books/

4.访问

我们在配置好url后,在url中输入v1,就会访问v1版本的接口

浅析Django接口版本控制

url中输入v2,就会访问v2版本的接口

浅析Django接口版本控制

3.3、NamespaceVersioning

对于客户端,此方案与URLPathVersioning相同。唯一的区别是,它是如何在 Django 应用程序中配置的,因为它使用URL conf中的命名空间而不是URL conf中的关键字参数。

使用此方案,request.version属性是根据与传入请求的路径匹配的 namespace 确定的。

如果你只需要一个简单的版本控制方案URLPathVersioningNamespaceVersioning都是合适的。URLPathVersioning这种方法可能更适合小型项目,对于更大的项目来说NamespaceVersioning可能更容易管理。

1.http访问方式

GET v1/something/ HTTP/1.1

Host: example.com

2.settings

REST_FRAMEWORK = {
	'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
        'DEFAULT_VERSION': 'v1',
        'ALLOWED_VERSIONS': ['v1', 'v2'],
}

3.urls

根urls.py中:

urlpatterns = [
    path('v1/api/', include('api.urls', namespace='v1')),
    path('v2/api/', include('api.urls', namespace='v2')),
]

说明:

增加了2个v1v2的不同的路由配置

4.访问

访问v1版本

浅析Django接口版本控制

访问v2版本

浅析Django接口版本控制

其余HostNameVersioningQueryParameterVersioning用的不多,想了解的可以查询官方文档

以上就是浅析Django接口版本控制的详细内容,更多关于Django接口版本控制的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python脚本在Appium库上对移动应用实现自动化测试
Apr 17 Python
Python编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
Jun 20 Python
django 在原有表格添加或删除字段的实例
May 27 Python
详解Python如何生成词云的方法
Jun 01 Python
解决python3读取Python2存储的pickle文件问题
Oct 25 Python
python游戏地图最短路径求解
Jan 16 Python
python使用thrift教程的方法示例
Mar 21 Python
django框架模型层功能、组成与用法分析
Jul 30 Python
python中web框架的自定义创建
Sep 08 Python
Django中ORM找出内容不为空的数据实例
May 20 Python
python查看矩阵的行列号以及维数方式
May 22 Python
python seaborn heatmap可视化相关性矩阵实例
Jun 03 Python
浅析Python实现DFA算法
解析目标检测之IoU
pycharm代码删除恢复的方法
Python max函数中key的用法及原理解析
Python访问Redis的详细操作
一文搞懂python异常处理、模块与包
Python实战之OpenCV实现猫脸检测
You might like
PHP中设置时区方法小结
2012/06/03 PHP
yii操作session实例简介
2014/07/31 PHP
用 Composer构建自己的 PHP 框架之设计 MVC
2014/10/30 PHP
浅析php设计模式之数据对象映射模式
2016/03/03 PHP
PHP将字符串首字母大小写转换的实例
2017/01/21 PHP
PHP实现给定一列字符,生成指定长度的所有可能组合示例
2019/06/22 PHP
nginx 设置多个站跨域
2021/03/09 Servers
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
2007/01/09 Javascript
Javascript 布尔型分析
2008/12/22 Javascript
为jquery.ui.dialog 增加“自动记住关闭时的位置”的功能
2009/11/24 Javascript
jQuery 源码分析笔记(3) Deferred机制
2011/06/19 Javascript
Event altKey,ctrlKey,shiftKey属性解析
2013/12/18 Javascript
jquery解析XML字符串和XML文件的方法说明
2014/02/21 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
JS实现灵巧的下拉导航效果代码
2015/08/25 Javascript
js以分隔符分隔数组中的元素并转换为字符串的方法
2016/11/16 Javascript
微信小程序 简单教程实例详解
2017/01/13 Javascript
使用express搭建一个简单的查询服务器的方法
2018/02/09 Javascript
详解Ubuntu安装angular-cli遇到的坑
2018/09/08 Javascript
微信小程序如何访问公众号文章
2019/07/08 Javascript
jQuery实现小火箭返回顶部特效
2020/02/03 jQuery
ant-design-vue中tree增删改的操作方法
2020/11/03 Javascript
[02:10]DOTA2 TI10勇士令状玩法及不朽Ⅰ展示:焕新世界,如你所期
2020/05/29 DOTA
django开发之settings.py中变量的全局引用详解
2017/03/29 Python
K-means聚类算法介绍与利用python实现的代码示例
2017/11/13 Python
在python中利用opencv简单做图片比对的方法
2019/01/24 Python
CSS3之边框多颜色Border-color属性使用示例
2013/10/11 HTML / CSS
CSS3 @keyframes简单动画实现
2018/02/24 HTML / CSS
Bose英国官方网站:美国知名音响品牌
2020/01/26 全球购物
璀璨的珍珠、密钉和个性化珠宝:Lily & Roo
2021/01/21 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
大学毕业自我鉴定范文
2014/02/03 职场文书
2014年秋季开学典礼主持词
2014/08/02 职场文书
2015年学校少先队工作总结
2015/07/20 职场文书
如何利用Python实现n*n螺旋矩阵
2022/01/18 Python
Python字符串格式化方式
2022/04/07 Python