django rest framework之版本的原始碼流程剖析
阿新 • • 發佈:2018-11-21
和之前的認證一樣在initial函式中:
1 def initial(self, request, *args, **kwargs): 2 """ 3 Runs anything that needs to occur prior to calling the method handler. 4 """ 5 self.format_kwarg = self.get_format_suffix(**kwargs) 6 7 # Perform content negotiation and store the accepted info on the request8 neg = self.perform_content_negotiation(request) 9 request.accepted_renderer, request.accepted_media_type = neg 10 11 # Determine the API version, if versioning is in use. 12 version, scheme = self.determine_version(request, *args, **kwargs) #獲取version號 13 request.version, request.versioning_scheme = version, scheme14 15 # Ensure that the incoming request is permitted 16 self.perform_authentication(request) 17 self.check_permissions(request) 18 self.check_throttles(request)
determine_version函式
1 def determine_version(self, request, *args, **kwargs): 2 """ 3 If versioning is being used, then determine any API version for the4 incoming request. Returns a two-tuple of (version, versioning_scheme) 5 """ 6 if self.versioning_class is None: #如果沒有設定version類就返回None 7 return (None, None) 8 scheme = self.versioning_class() #返回設定的版本類 9 return (scheme.determine_version(request, *args, **kwargs), scheme)
內建的路由version類
1 class URLPathVersioning(BaseVersioning): 2 """ 3 To the client this is the same style as `NamespaceVersioning`. 4 The difference is in the backend - this implementation uses 5 Django's URL keyword arguments to determine the version. 6 7 An example URL conf for two views that accept two different versions. 8 9 urlpatterns = [ 10 url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'), #在路由中必須這樣設定 11 url(r'^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail') 12 ] 13 14 GET /1.0/something/ HTTP/1.1 15 Host: example.com 16 Accept: application/json 17 """ 18 invalid_version_message = _('Invalid version in URL path.') 19 20 def determine_version(self, request, *args, **kwargs): 21 version = kwargs.get(self.version_param, self.default_version) #獲取版本號 22 if not self.is_allowed_version(version): #校驗版本號 23 raise exceptions.NotFound(self.invalid_version_message) 24 return version 25 26 def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra): 27 if request.version is not None: 28 kwargs = {} if (kwargs is None) else kwargs 29 kwargs[self.version_param] = request.version 30 #反向生成URL 31 return super(URLPathVersioning, self).reverse( 32 viewname, args, kwargs, request, format, **extra 33 )