Django Rest Framework(五) 之版本设置及源码流程

源码流程

www.example.com/api/v1/users/ ...

 

views.py示例

from django.shortcuts import render,HttpResponse

# Create your views here.

from rest_framework.views import APIView
from rest_framework.versioning import URLPathVersioning

class UserViews(APIView):


    def get(self,request,*args,**kwargs):
        # self.dispatch()
        print (request.version)
        return HttpResponse("test")

 

根据views.py分析源码流程

self.dispatch()入口,封装request(即self.initialize_request后)后执行 self.initial,查看源码

    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

        ##版本控制,request.version获取版本,version_scheme处理版本用的哪个对象
        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)

 

执行self.determine_version 方法,并将返回结果赋给request

    def determine_version(self, request, *args, **kwargs):
               if self.versioning_class is None:
            return (None, None)
     #实例化版本类的对象 scheme
= self.versioning_class()    #执行这个方法(如下),即读取配置文件里的DEFAUKT_VERSIONING_CLASS的值,还是老流程 return (scheme.determine_version(request, *args, **kwargs), scheme)      #这里的scheme为上面实例化的对象,所以自定义的版本类里肯定有 determine_version方法

 

class APIView(View):

    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS

 

配置示例

 

settings.py

REST_FRAMEWORK = {
    "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
    "DEFAULT_VERSION":"v1",
    "ALLOWED_VERSIONS":['v1','v2'],
    "VERSION_PARAM":'version'
}

:最后三行 适用于 http://www.xx.com/api/?version=v1..

 

views.py

from django.shortcuts import render,HttpResponse

from rest_framework.views import APIView
from rest_framework.versioning import URLPathVersioning

class UserViews(APIView):

    def get(self,request,*args,**kwargs):
        #self.dispatch()
        print (request.version)
     #反向生成url
     url_path = request.versioning_scheme.reverse(viewname="uuu",request=request)
     print (url_path)
     return HttpResponse("test")

 

urls.py

from django.conf.urls import url,include
from django.contrib import admin
from api import views

urlpatterns = [
    #这里的正则表达式根据URLPathVersioning这个类的示例获得
   url(r'^(?P<version>[v1|v2]+)/users/$',views.UserViews.as_view()),
]

 

posted @ 2018-07-10 21:51  FRESHMANS  阅读(127)  评论(0)    收藏  举报