规范开发api(版本携带)
在实际开发过程中,因为一个版本不可能更新的太快,所以在访问api接口,需要携带版本号,以便区分当前是哪个版本
举例说明:
总路由:
1 from django.contrib import admin 2 from django.urls import path, re_path, include 3 4 urlpatterns = [ 5 path('admin/', admin.site.urls), 6 re_path('api/', include('api.urls')), 7 ]
分发路由:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 from django.urls import path, re_path, include 5 from api import views 6 7 urlpatterns = [ 8 # 版本 9 re_path('(?P<version>[v1|v2]+)/users/$', views.UserView.as_view(), name='user'), 10 11 ]
表设计:
1 from django.db import models 2 3 4 class UserGroup(models.Model): 5 title = models.CharField(max_length=32) 6 7 8 class UserInfo(models.Model): 9 user_type_choices = ( 10 (1, '普通用户'), 11 (2, 'vip'), 12 (3, 'svip'), 13 ) 14 user_type = models.IntegerField(choices=user_type_choices) 15 username = models.CharField(max_length=32, unique=True) 16 password = models.CharField(max_length=64) 17 group = models.ForeignKey('UserGroup', on_delete=models.CASCADE) 18 roles = models.ManyToManyField('Role') 19 20 21 class UserToken(models.Model): 22 user = models.OneToOneField(to='UserInfo', on_delete=models.CASCADE) 23 token = models.CharField(max_length=64) 24 25 26 class Role(models.Model): 27 title = models.CharField(max_length=32)
视图中有自定义版本类,当然有内置的版本类,推荐使用URLPathVersioning,在url上一目了然
1 from django.shortcuts import render, HttpResponse, reverse 2 from rest_framework.views import APIView 3 from rest_framework.versioning import BaseVersioning, QueryParameterVersioning, URLPathVersioning 4 5 6 # #######################################版本########################## 7 class ParamVersion(BaseVersioning): 8 def determine_version(self, request, *args, **kwargs): 9 version = request.query_params.get('version') 10 return version 11 12 13 class UserView(APIView): 14 15 # versioning_class = URLPathVersioning 全局中已设置 16 17 def get(self, request, *args, **kwargs): 18 # http://127.0.0.1:8000/api/users/?version=v1 19 # version = request._request.GET.get('version') 20 # print(version) 21 # 获取版本 22 print(request.version) 23 # 获取处理版本对象 24 print(request.versioning_scheme) 25 # 反向生成url restframework 26 print(request.versioning_scheme.reverse(viewname='user', request=request)) 27 28 # 反向生成url利用django 29 print(reverse(viewname='user', kwargs={'version': 'v1'})) 30 return HttpResponse('用户列表')
全局配置:
1 REST_FRAMEWORK = { 2 # 版本 3 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', 4 'DEFAULT_VERSION': 'v1', 5 'ALLOWED_VERSIONS': ['v1', 'v2'], 6 'VERSION_PARAM': 'version', 7 }
版本源码流程分析
dispatch()->initialize_request->initial->determine_version->versioning_class若为None,则返回元组(None, None);反之若有self.versioning_class()版本类实例化,若没有默认配置文件中读versioning_class = api_settings.DEFAULT_VERSIONING_CLASS,返回元组,当前版本类和版本对象
若要自定义版本类:继承BaseVersioning必须实现determine_version方法
配置字段:
default_version = api_settings.DEFAULT_VERSION
allowed_versions = api_settings.ALLOWED_VERSIONS
version_param = api_settings.VERSION_PARAM
内置版本类
常用:
BaseVersioning *****
URLPathVersioning *****
QueryParameterVersioning
NamespaceVersioning
不常用:
AcceptHeaderVersioning
HostNameVersioning