You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FastAPI的Swagger UI中实现联动下拉菜单

问题背景

你现有一组问答数据,通过FastAPI+Pydantic搭建了提交接口,但在Swagger UI的表单中,选择下拉框的问题后无法自动关联填充对应答案,需要实现选问题自动填答案的动态联动效果。

现有代码

数据定义

quiz = [
    {'question': 'Cassandra',
     'response': '关系型', 
    },
    {'question': 'MongoDB et CouchDB',
     'response': '面向对象',
    },
]

my_question = tuple(q['question'] for q in quiz)

FastAPI模型与接口

from pydantic import BaseModel, Literal
from fastapi import FastAPI, Depends

api = FastAPI()
data = []

class Quiz(BaseModel):
    question: Literal[my_question]
    response: str

@api.post("/postdata")
def post_data(form_data: Quiz = Depends()):
    data.append(form_data)
    return data

解决方案

方案一:修改Swagger UI实现联动

通过给FastAPI的Swagger UI注入自定义JavaScript,监听下拉框变化并自动填充答案:

from fastapi import FastAPI, Depends
from fastapi.openapi.docs import get_swagger_ui_html
from pydantic import BaseModel, Literal

quiz = [
    {'question': 'Cassandra',
     'response': '关系型', 
    },
    {'question': 'MongoDB et CouchDB',
     'response': '面向对象',
    },
]

my_question = tuple(q['question'] for q in quiz)
quiz_json = str(quiz).replace("'", '"')  # 转成JS可识别的JSON格式

api = FastAPI(docs_url=None)  # 关闭默认docs路由
data = []

class Quiz(BaseModel):
    question: Literal[my_question]
    response: str

@api.post("/postdata")
def post_data(form_data: Quiz = Depends()):
    data.append(form_data)
    return data

# 自定义带联动逻辑的Swagger UI
@api.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
    return get_swagger_ui_html(
        openapi_url=api.openapi_url,
        title=api.title + " - Swagger UI",
        swagger_js_url="https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui-bundle.js",
        swagger_css_url="https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui.css",
        custom_js=f"""
        window.onload = function() {{
            const quizData = {quiz_json};
            // 监听表单渲染完成
            const observer = new MutationObserver((mutations) => {{
                mutations.forEach((mutation) => {{
                    if (mutation.addedNodes.length) {{
                        const questionSelect = document.querySelector('select[name="question"]');
                        if (questionSelect) {{
                            // 绑定下拉框变化事件
                            questionSelect.addEventListener('change', function() {{
                                const selected = this.value;
                                const match = quizData.find(item => item.question === selected);
                                if (match) {{
                                    const responseInput = document.querySelector('input[name="response"]');
                                    responseInput.value = match.response;
                                }}
                            }});
                            // 初始化填充默认问题的答案
                            const initialVal = questionSelect.value;
                            if (initialVal) {{
                                const match = quizData.find(item => item.question === initialVal);
                                const responseInput = document.querySelector('input[name="response"]');
                                responseInput.value = match.response;
                            }}
                            observer.disconnect();
                        }}
                    }}
                }});
            }});
            observer.observe(document.body, {{ childList: true, subtree: true }});
        }}
        """,
    )

方案二:自定义前端页面

如果不需要依赖Swagger UI,可直接写一个独立的HTML页面实现联动:

<!DOCTYPE html>
<html>
<head>
    <title>问答联动表单</title>
</head>
<body>
    <h3>选择问题提交</h3>
    <form id="quizForm">
        <div>
            <label for="question">问题:</label>
            <select id="question" name="question">
                <option value="Cassandra">Cassandra</option>
                <option value="MongoDB et CouchDB">MongoDB et CouchDB</option>
            </select>
        </div>
        <div>
            <label for="response">答案:</label>
            <input type="text" id="response" name="response" readonly>
        </div>
        <button type="submit">提交</button>
    </form>

    <script>
        const quizData = [
            {'question': 'Cassandra', 'response': '关系型'},
            {'question': 'MongoDB et CouchDB', 'response': '面向对象'}
        ];

        const questionSel = document.getElementById('question');
        const responseInput = document.getElementById('response');

        // 初始化填充第一个问题的答案
        responseInput.value = quizData[0].response;

        // 监听下拉框切换
        questionSel.addEventListener('change', function() {
            const selected = this.value;
            const match = quizData.find(item => item.question === selected);
            responseInput.value = match.response;
        });

        // 提交表单到FastAPI接口
        document.getElementById('quizForm').addEventListener('submit', async function(e) {
            e.preventDefault();
            const formData = Object.fromEntries(new FormData(this));
            const res = await fetch('/postdata', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(formData)
            });
            const result = await res.json();
            alert('提交成功!返回数据:' + JSON.stringify(result));
        });
    </script>
</body>
</html>

将该HTML文件放入FastAPI的静态资源目录,通过配置StaticFiles即可访问使用。

内容的提问来源于stack exchange,提问作者aba2s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 01:10:19