ソースコード解析の04 DRFバージョン
1.簡単なバージョン
APIのバージョンを使用すると、異なるクライアント間の動作を変更することができます。RESTフレームワークは、制御プログラムの異なるバージョンの数を提供します。
バージョン管理は、着信クライアント要求によって決定され、URLを要求することができるか、リクエストヘッダに基づきます。
APIのバージョンは、有効な
request.version
プロパティは、対応するバージョンを要求して、着信クライアント要求の文字列が含まれています。デフォルトでは、バージョン管理が有効になっていない、と
request.version
常に返しますNone
。
2.バージョン
プロファイルの設定
REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning', 'ALLOWED_VERSIONS':['v1','v2'], }
ルーティング
# 路由分发 urlpatterns = [ url(r'^api/(?P<version>\w+)/', include('api.urls')), ] # 子路由 urlpatterns = [ url(r'^order/$', views.OrderView.as_view()), ]
request.versionて値を取ることができます
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request class OrderView(APIView): def get(self,request,*args,**kwargs): print(request.version) print(request.versioning_scheme) return Response('...') def post(self,request,*args,**kwargs): return Response('post')
3.ソースコード解析
リクエストは発送方法を実行するようにしてい
class APIView(View): versioning_class = api_settings.DEFAULT_VERSIONING_CLASS def dispatch(self, request, *args, **kwargs): # 第一步 self.args = args self.kwargs = kwargs """ request = 生成了一个新的request对象,此对象的内部封装了一些值。 request = Request(request) - 内部封装了 _request = 老的request """ request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try: # 第二步 self.initial(request, *args, **kwargs) 执行视图函数...
初期の実行方法
def initial(self, request, *args, **kwargs): # 2.1 处理drf的版本 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme ...
determine_version
- versioning_classは、プロファイル設定にURLPathVersioningされます
def determine_version(self, request, *args, **kwargs): if self.versioning_class is None: return (None, None) scheme = self.versioning_class() # obj = XXXXXXXXXXXX() return (scheme.determine_version(request, *args, **kwargs), scheme)
方法は、次いでdetermine_versionオブジェクトに行われるURLPathVersioning
class URLPathVersioning(BaseVersioning): """ urlpatterns = [ url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'), ] """ 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
4.まとめ
- 最初の方法でディスパッチ処理方法の方法のdetermine_versionバージョンの実装上の要求
- クラスURLPathVersioningのsetings構成バージョンを見つけ、それをインスタンス化
- determine_version方法を実行するオブジェクトをインスタンス化し、
- この方法は、入力されたルーティングでバージョン情報を取得します
- is_allowed_version方法で設定構成設定ALLOWED_VERSIONSリスト内のURLのバージョンかどうかを決定します
- バージョンでrequest.versionに割り当てられます場合は、クラスのバージョンがrequest.versioning_schemeに割り当てられました