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"
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章