Django REST framework之版本实例以及版本源码流程分析

规范开发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
原文地址:https://www.cnblogs.com/Alexephor/p/11305906.html