热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

drf(五)—版本控制

drf(五)—版本控制1.源码流程与前几节的介绍相同源码入口依旧为dispatch()和inital();definitial(self,request,*args,**kwarg

drf(五)—版本控制

1.源码流程

与前几节的介绍相同源码入口依旧为dispatch()inital();

def initial(self, request, *args, **kwargs):
self.format_kwarg = self.get_format_suffix(**kwargs)
# Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
# 猜测可能是版本控制,进入查看。

# 将版本赋值给request对象。
request.version, request.versioning_scheme = version, scheme
# 因此,当我们想要获取版本的时候应该可以直接去request中进行查找
# Ensure that the incoming request is permitted
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)

determine_version() 函数。

def determine_version(self, request, *args, **kwargs):
if self.versioning_class is None:
return (None, None)#版本控制类不存在,返回值为None
scheme = self.versioning_class() # 实例化版本控制类的对象。
return (scheme.determine_version(request, *args, **kwargs), scheme)
# 返回值是两个对象,一个是执行函数,另一个是控制类的实例化对象
'''
版本控制类中使用的不是列表生成式,表明版本控制类只有一个而不是多个。
此处表明版本控制类中需要具备determine_version()方法。

结合上面函数猜想,返回值应该是版本与对象.
versioning_class指向配置文件。
'''

image-20220407203606146


2.自定义使用

class ParamVersion(object):
def determine_version(self, request, *args, **kwargs):
version = request.query_params.get('version')
return version

自定义的类中直接获取参数;

from app01.utils.version import ParamVersion
class VersionView(APIView):
throttle_classes = []
permission_classes = []
authentication_classes = [] #为方便验证直接将认证功能在该函数中取消。
versioning_class = ParamVersion #版本控制类不能使用列表,因此直接使用类名
def get(self,request,*args,**kwargs):
version=request.version
print(version)
return JsonResponse({"msg":"当前版本是%s"%(version)})

image-20220407211241476

此种方式使用较少,因为版本号通常是写在路由中而不是以参数的形式进行传播。


3.内置版本控制类

from rest_framework.versioning import URLPathVersioning,BaseVersioning

BaseVersioning类

class BaseVersioning:
default_version = api_settings.DEFAULT_VERSION # 读取配置文件
allowed_versiOns= api_settings.ALLOWED_VERSIONS
version_param = api_settings.VERSION_PARAM
def determine_version(self, request, *args, **kwargs):
msg = '{cls}.determine_version() must be implemented.'
raise NotImplementedError(msg.format(
cls=self.__class__.__name__
))
# 表明该方法必须被重写
def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
return _reverse(viewname, args, kwargs, request, format, **extra)
# 该方法可以进行路由解析

def is_allowed_version(self, version):
if not from rest_framework.versioning import URLPathVersioningself.allowed_versions:
return True
return ((version is not None and version == self.default_version) or
(version in self.allowed_versions))

URLPathVersioning 类

class URLPathVersioning(BaseVersioning):# 继承上述的类
"""
To the client this is the same style as `NamespaceVersioning`.
The difference is in the backend - this implementation uses
Django's URL keyword arguments to determine the version.
An example URL conf for two views that accept two different versions.
urlpatterns = [
re_path(r'^(?P[v1|v2]+)/users/$', users_list, name='users-list'),
# 使用动态路由进行传参。
re_path(r'^(?P[v1|v2]+)/users/(?P

[0-9]+)/$', users_detail, name='users-detail')
]
GET /1.0/something/ HTTP/1.1
Host: example.com
Accept: application/json
"""



invalid_version_message = _('Invalid version in URL path.')

# 重写该方法。
def determine_version(self, request, *args, **kwargs):
version = kwargs.get(self.version_param, self.default_version)
if version is None:
version = self.default_version
if not self.is_allowed_version(version):
raise exceptions.NotFound(self.invalid_version_message)
return version
# 路由解析,使用较少
def reverse(self,viewname,args=None,kwargs=None, request=None, format=None, **extra):
if request.version is not None:
kwargs = {} if (kwargs is None) else kwargs
kwargs[self.version_param] = request.version
return super().reverse(
viewname, args, kwargs, request, format, **extra
)

内置类封装的功能已经可以满足大多数功能。

全局配置:

image-20220407214230372

默认版本号,允许的版本号,版本参数名称。

REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":['app01.utils.auth.MyAuthentication',],
"UNAUTHENTICATED_USER":None, # 匿名,request.user = None
"UNAUTHENTICATED_TOKEN":None,
"DEFAULT_PERMISSION_CLASSES":['app01.utils.permission.MyPermission',],
"DEFAULT_THROTTLE_CLASSES":['app01.utils.throttle.MyThrottle',],
# 匿名用户不能在全局配置需要为登录功能单独添加
"DEFAULT_THROTTLE_RATES":{
"visit":'3/m',#一分钟三次,匿名用户
"loginuser":'10/m',# 登录成功,一分钟10次
},

# 版本的配置直接配置即可使用内置的版本控制类。
"DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
"DEFAULT_VERSION":'v1',
"ALLOWED_VERSIONS":['v1','v2'], #允许的版本号
"VERSION_PARAM":"version",# 这个参数应该和 路由中的名称相同version/
}

image-20220407214953729

继续努力,终成大器!



推荐阅读
  • Objective-C 中的委托模式详解与应用 ... [详细]
  • 第六章:枚举类型与switch结构的应用分析
    第六章深入探讨了枚举类型与 `switch` 结构在编程中的应用。枚举类型(`enum`)是一种将一组相关常量组织在一起的数据类型,广泛存在于多种编程语言中。例如,在 Cocoa 框架中,处理文本对齐时常用 `NSTextAlignment` 枚举来表示不同的对齐方式。通过结合 `switch` 结构,可以更清晰、高效地实现基于枚举值的逻辑分支,提高代码的可读性和维护性。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 本文详细探讨了MySQL数据库实例化参数的优化方法及其在实例查询中的应用。通过具体的源代码示例,介绍了如何高效地配置和查询MySQL实例,为开发者提供了有价值的参考和实践指导。 ... [详细]
  • 设计实战 | 10个Kotlin项目深度解析:首页模块开发详解
    设计实战 | 10个Kotlin项目深度解析:首页模块开发详解 ... [详细]
  • 本文探讨了Android系统中支持的图像格式及其在不同版本中的兼容性问题,重点涵盖了存储、HTTP传输、相机功能以及SparseArray的应用。文章详细分析了从Android 10 (API 29) 到Android 11 的存储规范变化,并讨论了这些变化对图像处理的影响。此外,还介绍了如何通过系统升级和代码优化来解决版本兼容性问题,以确保应用程序在不同Android版本中稳定运行。 ... [详细]
  • C++ 开发实战:实用技巧与经验分享
    C++ 开发实战:实用技巧与经验分享 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • CTF竞赛中文件上传技巧与安全绕过方法深入解析
    CTF竞赛中文件上传技巧与安全绕过方法深入解析 ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • 本文详细介绍了使用 Python 进行 MySQL 和 Redis 数据库操作的实战技巧。首先,针对 MySQL 数据库,通过 `pymysql` 模块展示了如何连接和操作数据库,包括建立连接、执行查询和更新等常见操作。接着,文章深入探讨了 Redis 的基本命令和高级功能,如键值存储、列表操作和事务处理。此外,还提供了多个实际案例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
  • JavaScript XML操作实用工具类:XmlUtilsJS技巧与应用 ... [详细]
  • 本文详细解析了微信服务端示例类的功能与应用。其中,`ClientResponseHandler` 类主要用于处理微信支付所需的响应数据,而 `TenpayHttpClient` 则是对 HTTP 请求(包括 GET 和 POST 方法)进行了封装,以便在内部调用时更加便捷和高效。这些工具类在实际开发中起到了关键作用,开发者无需深入了解其底层实现细节,即可轻松集成微信支付功能。 ... [详细]
  • PHP服务接口的专业测试方法与实践 ... [详细]
author-avatar
31號_K
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有