上一篇集成在了gatway上了,但给别人使用swagger的时候还是没有文档,如何集成swagger呢?
python版本:Python 3.11.5
Django版本:4.2.7
Swagger 是一种用于 RESTful API 的开源框架,可以帮助开发者快速构建和文档化 API。Swagger 文档提供了一种自动生成和可视化 API 文档的方式,使得 API 的设计和使用更加简单和易懂。Swagger 文档通过描述 API 的路径、参数、请求体、响应和错误码等信息,让开发者可以快速了解 API 的设计和使用方式,方便开发者进行 API 的集成和调用。
Swagger 2.0 是 Swagger 规范的第二个版本,引入了许多新的功能和改进。与第一个版本相比,Swagger 2.0 添加了对 WebSockets、OAuth2、文件上传和下载等功能的支持,并且提高了描述 API 的精确度和可读性。Swagger 2.0 还提供了一种可扩展的方式,让开发者可以为自己的 API 添加自定义的元数据信息。
OpenAPI 3.0 是 Swagger 的下一代规范,为 RESTful API 提供了一种标准的描述和交互方式。与 Swagger 2.0 相比,OpenAPI 3.0 提供了更严格的模式验证和错误处理,支持更多的数据类型和协议,同时还提供了更好的安全性和可扩展性。OpenAPI 3.0 还提供了更好的分层描述方式,让开发者可以更好地组织和管理 API 的文档。
那么我们怎么在 Django 项目中集成 Swagger 功能呢?我介绍两个工具 drf-yasg 和 drf-spectacular。
drf-yasg 介绍
https://github.com/axnsan12/drf-yasg
drf-yasg 也是一个基于 DRF 的 API 文档生成工具,同样支持 Swagger 2.0规范,并提供了自动生成文档和交互式文档页面的功能。它的特点是支持动态生成 Swagger UI,支持多种主题,可以自定义 API 文档样式,同时也提供了一些有用的功能,比如支持在文档中隐藏指定字段、支持在文档中添加额外的参数等。
drf-spectacular介绍
https://github.com/tfranzel/drf-spectacular
drf-spectacular 是一个基于 DRF 的 API 文档生成工具,支持 OpenAPI 3.0规范,并提供了自动生成文档和交互式文档页面的功能。它支持自定义的扩展和重载,可以满足不同项目的需求,同时还提供了一些有用的功能,比如支持通过代码自动注册 API 视图、支持自定义请求和响应验证器等。
如果新使用的是 OpenAPI 3.0 的文档,那么只能采用的是 drf-spectacular。
Drf-spectacular源码路径:GitHub - tfranzel/drf-spectacular: Sane and flexible OpenAPI 3 schema generation for Django REST framework.
版本信息查看,符合我的版本要求

大体安装流程

pip install drf-spectacular
配置安装程序
- INSTALLED_APPS = [
- # ALL YOUR APPS
- 'drf_spectacular',
- ]
在settings.py最下面注册到 DRF Django Rest Framework=>配置DRF默认schema
- REST_FRAMEWORK = {
- # YOUR SETTINGS
- 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
- }
还是在settings.py最下面,自定义OpenApi 描述
- SPECTACULAR_SETTINGS = {
- 'TITLE': 'Your Project API',
- 'DESCRIPTION': 'Your project description',
- 'VERSION': '1.0.0',
- 'SERVE_INCLUDE_SCHEMA': False,
- # OTHER SETTINGS
- }
drf-spectacular 默认不包含UI资源,采用CDN方式引入网络外部资源,如果需要本地使用UI资源,可以按照一下方式引入:
安装ui命令:
pip install drf-spectacular[sidecar]
配置settings.py文件
- INSTALLED_APPS = [
- # ALL YOUR APPS
- 'drf_spectacular',
- 'drf_spectacular_sidecar', # required for Django collectstatic discovery
- ]
- SPECTACULAR_SETTINGS = {
- 'SWAGGER_UI_DIST': 'SIDECAR', # shorthand to use the sidecar instead
- 'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
- 'REDOC_DIST': 'SIDECAR',
- # OTHER SETTINGS
- }
注意:SPECTACULAR_SETTINGS,与之前的重复进行合并处理
在根urls.py中增加路由配置
- from drf_spectacular.views import SpectacularJSONAPIView, SpectacularRedocView, SpectacularSwaggerView
-
- urlpatterns = [
- path('swagger/json/', SpectacularJSONAPIView.as_view(), name='schema'),
- # Optional UI:
- path('swagger/ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
- path('swagger/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), # YOUR PATTERNS
- ]
访问路径:http://localhost:8000/swagger/ui/

文档没有接口,是因为我们接口还没有添加api注释相关的内容。如何使用呢?
官方给的截图
- from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiExample
- from drf_spectacular.types import OpenApiTypes
-
- class AlbumViewset(viewset.ModelViewset):
- serializer_class = AlbumSerializer
-
- @extend_schema(
- request=AlbumCreationSerializer,
- responses={201: AlbumSerializer},
- )
- def create(self, request):
- # your non-standard behaviour
- return super().create(request)
-
- @extend_schema(
- # extra parameters added to the schema
- parameters=[
- OpenApiParameter(name='artist', description='Filter by artist', required=False, type=str),
- OpenApiParameter(
- name='release',
- type=OpenApiTypes.DATE,
- location=OpenApiParameter.QUERY,
- description='Filter by release date',
- examples=[
- OpenApiExample(
- 'Example 1',
- summary='short optional summary',
- description='longer description',
- value='1993-08-23'
- ),
- ...
- ],
- ),
- ],
- # override default docstring extraction
- description='More descriptive text',
- # provide Authentication class that deviates from the views default
- auth=None,
- # change the auto-generated operation name
- operation_id=None,
- # or even completely override what AutoSchema would generate. Provide raw Open API spec as Dict.
- operation=None,
- # attach request/response examples to the operation.
- examples=[
- OpenApiExample(
- 'Example 1',
- description='longer description',
- value=...
- ),
- ...
- ],
- )
- def list(self, request):
- # your non-standard behaviour
- return super().list(request)
-
- @extend_schema(
- request=AlbumLikeSerializer,
- responses={204: None},
- methods=["POST"]
- )
- @extend_schema(description='Override a specific method', methods=["GET"])
- @action(detail=True, methods=['post', 'get'])
- def set_password(self, request, pk=None):
- # your action behaviour
- ...
找一个最简单的接口添加
- from rest_framework.decorators import api_view
- from drf_spectacular.utils import extend_schema, OpenApiExample, inline_serializer
- @extend_schema(
- responses={
- (200, 'text/html'): {
- 'description': 'Simple HTML page',
- 'type': 'string',
- 'example': 'Example text'
- },
- (202, 'application/json'): {
- 'description': 'JSON response',
- 'type': 'object',
- 'properties': {
- 'title': {
- 'type': 'string',
- 'minLength': 1,
- 'maxLength': 128
- }
- },
- 'required': [
- 'title'
- ]
- },
- }
- )
- @api_view(['GET'])
- def test2(request):
- # cache.set('hobby', 'film')
- print(cache.get('hobby'))
- return HttpResponse('缓存成功')
在访问刚才的swagger地址

如果想要修改指定接口所属的标签,我们可以使用drf-spectacular提供的extend_schema装饰器函数,函数定义如下:

- def extend_schema(
- operation_id: Optional[str] = None,
- parameters: Optional[Sequence[Union[OpenApiParameter, _SerializerType]]] = None,
- request: Any = empty,
- responses: Any = empty,
- auth: Optional[Sequence[str]] = None,
- description: Optional[_StrOrPromise] = None,
- summary: Optional[_StrOrPromise] = None,
- deprecated: Optional[bool] = None,
- tags: Optional[Sequence[str]] = None,
- filters: Optional[bool] = None,
- exclude: Optional[bool] = None,
- operation: Optional[Dict] = None,
- methods: Optional[Sequence[str]] = None,
- versions: Optional[Sequence[str]] = None,
- examples: Optional[Sequence[OpenApiExample]] = None,
- extensions: Optional[Dict[str, Any]] = None,
- callbacks: Optional[Sequence[OpenApiCallback]] = None,
- external_docs: Optional[Union[Dict[str, str], str]] = None,
- ) -> Callable[[F], F]:
这个装饰器主要用于修改view在文档中的定义,参数意义如下:
operation_id:一个唯一标识ID,基本用不到
parameters:添加到列表中的附加或替换参数去自动发现字段。
responses:替换Serializer。需要各种各样的可单独使用或组合使用的输入(有以下7种) Serializer类 序列化实例,比如:Serializer(many=True) OpenApiTypes的基本类型或者实例 OpenApiResponse类 PolymorphicProxySerializer类 1个字典,以状态码作为键, 以上其中一项作为值(是最常用的,格式{200, None}) 1个字典,以状态码作为键,以media_type作为值
request:替换序列化,接受各种输入 Serializer 类或者实例 OpenApiTypes基本类型或者实例 PolymorphicProxySerializer类 1个字典,以media_type作为键,以上其中一项作为值
auth:用auth方法的显式列表替换发现的auth
description:替换发现的文档字符串
summary:一个可选的短的总结描述
deprecated:将操作标记为已弃用
tags:覆盖默认标记列表
exclude:设置为True以从schema中排除操作
operation:手动覆盖自动发现将生成的内容。你必须提供一个兼容OpenAPI3的字典,该字典可以直接翻译成YAML。
methods:检查extend_schema中特殊的方法,默认匹配所有
versions:检查extend_schema中特殊的API版本,默认匹配所有
example:将请求/响应示例附加到操作中
extensions:规范扩展