1. GET parameter to get version
The RESTful specification specifies that the version can be placed on the URL, such as http://127.0.0.1:8000/api/users/?version=v2 transfers parameters through GET. Custom version implementation:
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView from rest_framework.request import Request from rest_framework.versioning import BaseVersioning class ParamVersion: def determine_version(self, request, *args, **kwargs): # version = request._request.GET.get('version') version = request.query_params.get('version') return version class UsersView(APIView): versioning_class = ParamVersion # request.version It will be worth it def get(self, request, *args, **kwargs): # Request is the object of request. If the encapsulated request does not return to the native Django request through the getattr method # version = request._request.GET.get('version') # version = request.query_params.get('version') version = request.version # print(request.version) return HttpResponse('%s' % version)
If we use the built-in version class, in fact, we do not need to customize the class to get the version, and we can directly use the view class method to get the version request.version Just get it, because the built-in already helps us implement it. With built-in classes, we can write a lot less code:
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView from rest_framework.versioning import QueryParameterVersioning class UsersView(APIView): versioning_class = QueryParameterVersioning def get(self, request, *args, **kwargs): version = request.version return HttpResponse('%s' % version)
You can do the default configuration in the configuration file:
REST_FRAMEWORK = { 'DEFAULT_VERSION': 'v1', # If the parameter is not passed or the version is wrongly written, the version number obtained is v1 'ALLOWED_VERSIONS': ['v1', 'v2'], # The version number must be v1 or v2, otherwise an error is reported, such as: http://xxx/api/users/?version=v3 'VERSION_PARAM': 'version', }
2. URL path to get version
It is relatively less to use GET to transfer parameters, and more to upload parameters in URL path, that is, ''. Just modify the URL and introduce the URLPathVersioning built-in version class in the view:
api/urls.py:
from django.urls import path, re_path from . import views urlpatterns = [ # path('/users/', views.UsersView.as_view()), re_path('(?P<version>[v1,v2]+)/users/', views.UsersView.as_view()), ]
Version is a one-time configuration. You can add the class of the version to the configuration file
settings.py:
REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # Using URL path, the following parameters can be unconfigured, as long as URL regular matching is OK 'DEFAULT_VERSION': 'v1', # If the parameter is not passed or the version is wrong, the version number obtained is v1 'ALLOWED_VERSIONS': ['v1', 'v2'], # The version number must be v1 or v2, otherwise an error is reported, such as: http://xxx/api/users/?version=v3 'VERSION_PARAM': 'version', }
The built-in class QueryParameterVersioning, which is applicable to GET parameter transfer, can also be put into the configuration file, which reduces the coupling between classes.
views.py:
from django.shortcuts import render, HttpResponse from rest_framework.views import APIView class UsersView(APIView): def get(self, request, *args, **kwargs): version = request.version return HttpResponse('%s' % version)
3. Built in version class source code process
Reverse generate url through reserve:
from django.urls import path, re_path from . import views urlpatterns = [ # path('users/', views.UsersView.as_view()), re_path('(?P<version>[v1,v2]+)/users/', views.UsersView.as_view(), name='user'), ]
from django.shortcuts import HttpResponse from rest_framework.views import APIView class UsersView(APIView): def get(self, request, *args, **kwargs): # Get version version = request.version # Gets the object that processes the version versioning_scheme = request.versioning_scheme # All version class objects have the reverse method to generate the url in reverse, and the version is generated automatically. You do not need to add the version parameter. request=request indicates the current version on the request auto setting url = request.versioning_scheme.reverse(viewname='user', request=request) self.dispatch return HttpResponse('%s' % (url,))
You can also use Django's reverse generated url, but manually add the version parameter:
4. Built in version class
Django REST framework has five built-in version classes. The custom version class needs to inherit BaseVersioning, but generally we don't need to customize. The built-in version class is enough for us to use. QueryParameterVersioning is to use GET parameter in URL; URLPathVersioning is URL path; HostNameVersioning is based on subdomain name; NamespaceVersioning is based on namespace, but not commonly used; AcceptHeaderVersioning is based on request header.
It's OK to put it in the cookie, as long as the back-end can receive it normally.