如何在不重写模板的情况下用drf-yasg实现API版本下拉切换?
实现方案
无需重写drf-yasg默认模板即可实现API版本下拉选择,仅展示选定版本的API路径。核心是结合DRF版本控制、动态生成对应版本的Schema,以及利用swagger-ui对枚举类型参数的原生下拉渲染支持。
1. 配置DRF版本控制
首先在settings.py中配置DRF的查询参数版本控制,通过?version=xxx的方式切换版本:
REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning', 'ALLOWED_VERSIONS': ['v1', 'v2', 'v3'], # 替换为你的可用版本列表 'DEFAULT_VERSION': 'v1', }
2. 自定义版本化SchemaView
创建继承自drf-yasg SchemaView的类,动态根据请求的version参数生成对应版本的Schema,自动过滤非当前版本的API:
from drf_yasg.views import get_schema_view from drf_yasg import openapi from rest_framework.versioning import QueryParameterVersioning from django.urls import path, include # 生成基础SchemaView base_schema_view = get_schema_view( openapi.Info( title="你的API文档", default_version='v1', description="支持版本切换的API文档", ), public=True, patterns=[path('api/', include('your_api_urls'))], # 替换为你的API路由 ) class VersionedSchemaView(base_schema_view.__class__): def get_schema(self, request=None, public=False): if request: # 从查询参数获取目标版本,无则用默认版本 target_version = request.query_params.get('version', self.versioning_class.default_version) # 手动设置request的版本信息,触发DRF版本控制逻辑 request.version = target_version request.versioning_scheme = QueryParameterVersioning() # 生成仅包含当前版本API的Schema return super().get_schema(request, public) # 实例化自定义SchemaView schema_view = VersionedSchemaView( swagger_ui_settings={ 'defaultModelsExpandDepth': -1, # 可选:关闭模型展开,简化页面 } ) # 添加全局版本参数,swagger-ui会自动渲染为下拉框 schema_view.schema.parameters.append( openapi.Parameter( name='version', in_=openapi.IN_QUERY, description='选择API版本', type=openapi.TYPE_STRING, enum=['v1', 'v2', 'v3'], # 与ALLOWED_VERSIONS保持一致 default='v1' ) )
3. 注册路由
在urls.py中注册自定义的SchemaView:
from django.urls import path from .views import schema_view urlpatterns = [ path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), # 其他业务路由... ]
关键说明
- 无需修改模板:swagger-ui原生支持将枚举类型的查询参数渲染为下拉选择框,切换版本时页面会自动重新加载对应版本的API文档。
- 版本过滤逻辑:DRF的版本控制会自动过滤掉不属于当前版本的视图,最终生成的Schema仅包含选定版本的API路径。
- 缓存设置:将
cache_timeout设为0,避免切换版本后显示旧版本的缓存文档。
内容的提问来源于stack exchange,提问作者Faizan AlHassan
相关产品推荐
相关产品推荐

