我尝试使用Django REST Framework实现API并在Swagger UI中显示模式

首先

我之前使用Django REST Framework(DRF)创建了一个API。
考虑到需要创建API文档,我也开始倾向于使用FastAPI,因为它作为基本功能支持Swagger文档生成,但是我发现Django的强大管理功能对业务应用来说仍然是不可或缺的。
在研究如何使用DRF来轻松创建API文档时,我发现只需稍作改进就可以像FastAPI一样自动创建API文档。
本次我将在这里记录使用DRF实现的API自动化生成API文档的步骤。

借用先人智慧成功解决的事情,在这个场合中,我感谢并非常抱歉地将其作为我个人的备忘录整理到这里。

以下是将在此次使用的环境中使用的版本:

Windows 11专业版 22H2
Python 3.12.0
Django 4.2.6
Django REST框架 3.14.0
SQLite 3.43.1

1. Swagger 是什么?

Swagger是一個用於構建RESTful API的開源框架。
Swagger是由「Open API Initiative」推動的,用於描述RESTful API接口的標準格式。Swagger還提供了許多實用工具,這使得它的優勢更加明顯。
通過編寫Swagger Spec,不僅可以自動生成文檔,還可以從文檔中發送實際的請求,這是一個非常出色的功能。

与Swagger相关的术语

用語説明Swagger SpecificationSwaggerを扱う上で中心となる概念で、Swaggerの仕様に準じた、RESTful APIインターフェイスを記述するためのフォーマット(YAML/JSON)。Swagger Editorなどで編集するときには、YAMLを用いる方が扱いやすいが、外部のライブラリやSwagger UIと連携する場合にはJSON形式で使用。OpenAPI SpecificationSwaggerをベースに作られたRESTful APIインターフェイスを記述するためのフォーマット(JSON)。Swagger Editerブラウザ上で動くSwagger Specificationの設計書を記載するためのエディタ。リアルタイムで構文チェック、可視化。Swagger UISwagger Specificationで記載された設計からドキュメントをHTML形式で自動生成するツール。Swagger CodegenSwagger Specificationで記載された設計からクライアントコード生成するコマンドラインツール。APIのスタブを自動生成する。

 

创建API文档。

安裝OpenAPI Renderer所需的程式庫。

在运行Django项目的Python虚拟环境中执行命令。

(venv) pip install pyyaml
(venv) pip install uritemplate

编辑django项目目录中的urls.py文件。

在项目级别的路由中添加到模式的路由。

from django.contrib import admin
from django.urls import include, path
+ from rest_framework.schemas import get_schema_view
+ from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),

    ...

+     path('schema/', get_schema_view(          # スキーマ表示の追加
+         title="任意",
+         description="任意"
+     ), name='openapi-schema'),
+     path('docs/', TemplateView.as_view(       # ドキュメント表示の追加
+         template_name='swagger-ui.html',
+         extra_context={'schema_url':'openapi-schema'}
+     ), name='swagger-ui'),
]

创建模板文件

需要一个用于显示文档的模板文件,所以在project/settings.py中设置模板目录。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
-         'DIRS': [], # リスト内に追記
+         'DIRS': ['templates'],       # リスト内に追記
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

為了適應上述的設置,我們將在django項目的根目錄下創建一個名為templates/的文件夾。
有一些模板可以用於顯示契約文檔,但我們這次要使用swagger-ui.html模板,所以我們將創建templates/swagger-ui.html文件,並添加以下代碼。

<!DOCTYPE html>
<html>
  <head>
    <title>API References</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="//unpkg.com/swagger-ui-dist@3/swagger-ui.css" />
  </head>
  <body>
    <div id="swagger-ui"></div>
    <script src="//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
    <script>
    const ui = SwaggerUIBundle({
        url: "{% url schema_url %}",
        dom_id: '#swagger-ui',
        presets: [
          SwaggerUIBundle.presets.apis,
          SwaggerUIBundle.SwaggerUIStandalonePreset
        ],
        layout: "BaseLayout"
      })
    </script>
  </body>
</html>

假设以先前创建的DRF API为例,其目录结构如下所示。

 

root (プロジェクトルート)
├ djangoApiApp (プロジェクト)
  ├ __pycache____init__.pyasgi.pysettings.pywsgi.pyproducts (アプリケーション)
  ├ __pycache__migtarions__init__.pyadmin.pyapps.pymodels.pyserializers.pytests.pyurls.pyviews.pytemplates            # 追加
swagger-ui.html    # 追加
venvIncludeLibScriptspyvenv.cfg
.env
db.sqlite3
manage.py

2-4) 查看 API 文档

当你访问http://localhost:8000/schema/ 或者http://localhost:8000/docs/,你可以以各自的展示格式来查看API的模式。(也可以将localhost替换为127.0.0.1)

image.png
image.png

这次的源代码已经提交到GitHub上了。

 


只需要一种选项

开放API规范

 

风姿摇曳

 

好像也有一种叫做 “ReDoc” 的东西…

 


(编辑后记)

(编辑者注)

这次我们使用Django REST Framework来实现API的代码,并生成了Swagger规范,可以在Swagger UI中显示。
通常情况下,应该按照设计→实现的顺序进行,但是以往我经历过改进代码却没有改进文档的系统,真的很讨厌。
虽然这是一种通过实现来生成API文档的逆向工程,但它始终可以反映最新的实现,我认为这是非常好的。
在DRF和FastAPI中都可以实现类似的功能,我个人非常满意。希望这对大家有所帮助。

bannerAds