1. 程式人生 > >django rest framework之版本的原始碼流程剖析

django rest framework之版本的原始碼流程剖析

和之前的認證一樣在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 request
8 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, scheme
14 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 the
4 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         )