rest_framework学习之“版本解析”

rest_framework的版本解析步奏在认证、权限、节流之前,同样是从dispatch的initial方法进入,然后运行self.determine_version方法,返回的结果就是API的版本号
def initial(self, request, *args, **kwargs):
	self.format_kwarg = self.get_format_suffix(**kwargs)
	neg = self.perform_content_negotiation(request)
	request.accepted_renderer, request.accepted_media_type = neg
	version, scheme = self.determine_version(request, *args, **kwargs)  # 版本解析
	request.version, request.versioning_scheme = version, scheme
	# 认证
	self.perform_authentication(request)
	# 权限
	self.check_permissions(request)
	# 节流
	self.check_throttles(request)
一、 determine_version
  • 在determine_version方法中,如果视图类或者项目配置中没有解析版本的类(self.versioning_class),那么直接返回(None, None)元组,即version=None,没有解析版本。
  • 如果视图类或者项目配置中配置了解析版本的类(self.versioning_class),那么将实例化该类,并返回该对象的determine_version方法的返回值以及该类的实例化对象。
def determine_version(self, request, *args, **kwargs):
	if self.versioning_class is None:
		return (None, None)
	# 将解析版本的类实例化
	scheme = self.versioning_class()
	# 返回determine_version方法的返回值以及实例化对象
	return (scheme.determine_version(request, *args, **kwargs), scheme)
二、 根据restful设计规范,我们会使用rest_framework内置的URLPathVersioning来对API的版本进行解析。
  • URLPathVersioning继承了BaseVersioning类,保留了is_allowed_version方法和几个属性:
# 默认的版本号
default_version = api_settings.DEFAULT_VERSION
# 允许的版本号,如果API中的版本不再该范围内则抛出异常
allowed_versions = api_settings.ALLOWED_VERSIONS
# 在路由解析时对版本号解析使用的关键字名称,一般是version
version_param = api_settings.VERSION_PARAM
# 判断解析成功的版本号是否在允许访问范围内
def is_allowed_version(self, version):
	if not self.allowed_versions:
		return True
	return ((version is not None and version == self.default_version) or (version in self.allowed_versions))
  • URLPathVersioning要求我们在设计API的路由解析包含"version"名称的正则解析关键字:
urlpatterns = [
	url(r'^(?P<version>.+)/users/$'),
]
  • URLPathVersioning的determine_version方法先从kwargs中获取以self.version_param为名称的参数(即"version"),如果获取失败,那么将self.default_version(默认版本号)赋值给version。完成解析后还会执行self.is_allowed_version验证该版本号是否在允许访问的范围里,否则抛出NotFound异常:
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
三、版本解析类的全局配置

通常我们会将版本解析类全局布置,那么只需将以下几个参数设置在settings.py文件里即可:

REST_FRAMEWORK = {
	# 默认版本号
    "DEFAULT_VERSION": "v1",
	# 允许访问的版本号
	"ALLOWED_VERSIONS": ["v1", "v2"],
	# 从路由解析中获取版本参数的名称
	"VERSION_PARAM": "version",
	# 版本解析类
	"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning"
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章