drf(五)—版本控制
2022/4/7 23:51:37
本文主要是介绍drf(五)—版本控制,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
drf(五)—版本控制
1.源码流程
与前几节的介绍相同源码入口依旧为dispatch()
和inital()
;
def initial(self, request, *args, **kwargs): self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) # 猜测可能是版本控制,进入查看。 # 将版本赋值给request对象。 request.version, request.versioning_scheme = version, scheme # 因此,当我们想要获取版本的时候应该可以直接去request中进行查找 # Ensure that the incoming request is permitted self.perform_authentication(request) self.check_permissions(request) self.check_throttles(request)
determine_version() 函数。
def determine_version(self, request, *args, **kwargs): if self.versioning_class is None: return (None, None)#版本控制类不存在,返回值为None scheme = self.versioning_class() # 实例化版本控制类的对象。 return (scheme.determine_version(request, *args, **kwargs), scheme) # 返回值是两个对象,一个是执行函数,另一个是控制类的实例化对象 ''' 版本控制类中使用的不是列表生成式,表明版本控制类只有一个而不是多个。 此处表明版本控制类中需要具备determine_version()方法。 结合上面函数猜想,返回值应该是版本与对象. versioning_class指向配置文件。 '''
2.自定义使用
class ParamVersion(object): def determine_version(self, request, *args, **kwargs): version = request.query_params.get('version') return version
自定义的类中直接获取参数;
from app01.utils.version import ParamVersion class VersionView(APIView): throttle_classes = [] permission_classes = [] authentication_classes = [] #为方便验证直接将认证功能在该函数中取消。 versioning_class = ParamVersion #版本控制类不能使用列表,因此直接使用类名 def get(self,request,*args,**kwargs): version=request.version print(version) return JsonResponse({"msg":"当前版本是%s"%(version)})
此种方式使用较少,因为版本号通常是写在路由中而不是以参数的形式进行传播。
3.内置版本控制类
from rest_framework.versioning import URLPathVersioning,BaseVersioning
BaseVersioning类
class BaseVersioning: default_version = api_settings.DEFAULT_VERSION # 读取配置文件 allowed_versions = api_settings.ALLOWED_VERSIONS version_param = api_settings.VERSION_PARAM def determine_version(self, request, *args, **kwargs): msg = '{cls}.determine_version() must be implemented.' raise NotImplementedError(msg.format( cls=self.__class__.__name__ )) # 表明该方法必须被重写 def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra): return _reverse(viewname, args, kwargs, request, format, **extra) # 该方法可以进行路由解析 def is_allowed_version(self, version): if not from rest_framework.versioning import URLPathVersioningself.allowed_versions: return True return ((version is not None and version == self.default_version) or (version in self.allowed_versions))
URLPathVersioning 类
class URLPathVersioning(BaseVersioning):# 继承上述的类 """ To the client this is the same style as `NamespaceVersioning`. The difference is in the backend - this implementation uses Django's URL keyword arguments to determine the version. An example URL conf for two views that accept two different versions. urlpatterns = [ re_path(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'), # 使用动态路由进行传参。 re_path(r'^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail') ] GET /1.0/something/ HTTP/1.1 Host: example.com Accept: application/json """ invalid_version_message = _('Invalid version in URL path.') # 重写该方法。 def determine_version(self, request, *args, **kwargs): version = kwargs.get(self.version_param, self.default_version) if version is None: version = self.default_version if not self.is_allowed_version(version): raise exceptions.NotFound(self.invalid_version_message) return version # 路由解析,使用较少 def reverse(self,viewname,args=None,kwargs=None, request=None, format=None, **extra): if request.version is not None: kwargs = {} if (kwargs is None) else kwargs kwargs[self.version_param] = request.version return super().reverse( viewname, args, kwargs, request, format, **extra )
内置类封装的功能已经可以满足大多数功能。
全局配置:
默认版本号,允许的版本号,版本参数名称。
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":['app01.utils.auth.MyAuthentication',], "UNAUTHENTICATED_USER":None, # 匿名,request.user = None "UNAUTHENTICATED_TOKEN":None, "DEFAULT_PERMISSION_CLASSES":['app01.utils.permission.MyPermission',], "DEFAULT_THROTTLE_CLASSES":['app01.utils.throttle.MyThrottle',], # 匿名用户不能在全局配置需要为登录功能单独添加 "DEFAULT_THROTTLE_RATES":{ "visit":'3/m',#一分钟三次,匿名用户 "loginuser":'10/m',# 登录成功,一分钟10次 }, # 版本的配置直接配置即可使用内置的版本控制类。 "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning", "DEFAULT_VERSION":'v1', "ALLOWED_VERSIONS":['v1','v2'], #允许的版本号 "VERSION_PARAM":"version",# 这个参数应该和 路由中的名称相同version/ }
继续努力,终成大器!
这篇关于drf(五)—版本控制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?