ソースコード解析の04 DRFバージョン

ソースコード解析の04 DRFバージョン

1.簡単なバージョン

  • APIのバージョンを使用すると、異なるクライアント間の動作を変更することができます。RESTフレームワークは、制御プログラムの異なるバージョンの数を提供します。

  • バージョン管理は、着信クライアント要求によって決定され、URLを要求することができるか、リクエストヘッダに基づきます。

  • APIのバージョンは、有効なrequest.versionプロパティは、対応するバージョンを要求して、着信クライアント要求の文字列が含まれています。

  • デフォルトでは、バージョン管理が有効になっていない、とrequest.version常に返しますNone

2.バージョン

  1. プロファイルの設定

    REST_FRAMEWORK = {
        'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
     'ALLOWED_VERSIONS':['v1','v2'],
    
    }
  2. ルーティング

    # 路由分发
    urlpatterns = [
        url(r'^api/(?P<version>\w+)/', include('api.urls')),
    ]
    
    # 子路由
    urlpatterns = [
        url(r'^order/$', views.OrderView.as_view()),
    ]
  3. 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.まとめ

  1. 最初の方法でディスパッチ処理方法の方法のdetermine_versionバージョンの実装上の要求
  2. クラスURLPathVersioningのsetings構成バージョンを見つけ、それをインスタンス化
  3. determine_version方法を実行するオブジェクトをインスタンス化し、
  4. この方法は、入力されたルーティングでバージョン情報を取得します
  5. is_allowed_version方法で設定構成設定ALLOWED_VERSIONSリスト内のURLのバージョンかどうかを決定します
  6. バージョンでrequest.versionに割り当てられます場合は、クラスのバージョンがrequest.versioning_schemeに割り当てられました

おすすめ

転載: www.cnblogs.com/liubing8/p/11939525.html