fastapi:wtforms库的应用

📅 2026/7/26 22:40:03 👁️ 阅读次数 📝 编程学习
fastapi:wtforms库的应用

一,官方站

库地址:

https://pypi.org/project/WTForms/

代码站:

https://github.com/pallets-eco/wtforms/

文档:

https://wtforms.readthedocs.io/en/3.2.x/

二,代码:

python

router = APIRouter(prefix="/test", tags=["测试"])# 1. 定义 WTForms 表单类
class DemoForm(WTForm):# Select 元素:下拉选择框# choices 接收一个由 (值, 显示文本) 组成的元组列表city = SelectField("选择城市",choices=[(0, "北京"), (1, "上海"), (2, "广州")], default=0,validators=[DataRequired(message="请选择一个城市")],)# Radio 元素:单选框gender = RadioField("性别",choices=[(1, "男"), (0, "女")],default=1,validators=[DataRequired(message="请选择性别")],)# Textarea 元素:多行文本输入框bio = TextAreaField("个人简介", validators=[DataRequired(message="请输入个人简介")])# 2. GET 路由:渲染包含空表单的页面
@router.api_route("/demo", methods=["GET", "POST"], response_class=HTMLResponse)
async def show_form(request: Request):if request.method == "GET":form = DemoForm()return templates.TemplateResponse(request=request,name="test/demo.html",context={"request": request, "form": form, "title": "登录"})elif request.method == "POST":# 将 FastAPI 接收到的 FormData 转换为 WTForms 需要的格式form_data = await request.form()form = DemoForm(form_data)if form.validate():print("city:", form.city.data)print("gender:", form.gender.data)print("bio:", form.bio.data)# 返回成功return JSONResponse({"status_code": 200, "detail": "提交成功", "data": {}})else:print(form.errors)error_msg = "; ".join([f"{field}: {', '.join(errors)}" for field, errors in form.errors.items()])# 返回异常return JSONResponse({"status_code": 400, "detail": error_msg, "data": {}})

html:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>FastAPI + WTForms 动态表单</title><!-- 引入简易 CSS 框架让页面好看一点 --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@example/water.css@2/out/water.css"><style>.error-msg { color: #ff4d4f; font-size: 0.9em; margin-top: 5px; }.radio-group { display: flex; gap: 15px; align-items: center; margin: 10px 0; }.radio-item { display: inline-flex; align-items: center; gap: 5px; }.success-box { background-color: #e6f7ff; border: 1px solid #91d5ff; padding: 15px; border-radius: 4px; margin-bottom: 20px; }.form-radio {list-style-type: none;padding-inline-start: 0px;padding-top: 6px;display: flex;gap: 20px;
}</style></head>
<body><h2>FastAPI + WTForms 动态表单示例</h2><!-- 显示提交成功后的结果 -->{% if result %}<div class="success-box"><strong>{{ result }}</strong></div>{% endif %}<form method="POST" action=""><!-- 1. 动态生成 Select 下拉框 --><div style="margin-bottom: 20px;"><label>{{ form.city.label }}</label>{{ form.city(class="form-select") }}{% if form.city.errors %}{% for error in form.city.errors %}<div class="error-msg">{{ error }}</div>{% endfor %}{% endif %}</div><!-- 2. 动态生成 Radio 单选框 Radio 需要循环遍历里面的选项单独渲染<div style="margin-bottom: 20px;"><label>{{ form.gender.label }}</label><div class="radio-group">{% for subfield in form.gender %}<span class="radio-item">{{ subfield }}{{ subfield.label }}</span>{% endfor %}</div>{% if form.gender.errors %}{% for error in form.gender.errors %}<div class="error-msg">{{ error }}</div>{% endfor %}{% endif %}</div>--><!-- 2. 动态生成 Radio 单选框 --><div style="margin-bottom: 20px;"><label>{{ form.gender.label }}</label>{{ form.gender(class="form-radio") }}{% if form.gender.errors %}{% for error in form.gender.errors %}<div class="error-msg">{{ error }}</div>{% endfor %}{% endif %}</div><!-- 3. 动态生成 Textarea 多行文本 --><div style="margin-bottom: 20px;"><label>{{ form.bio.label }}</label><!-- 可以在括号里直接控制 rows 和 cols 等 HTML 属性 -->{{ form.bio(rows="5", style="width: 100%;") }}{% if form.bio.errors %}{% for error in form.bio.errors %}<div class="error-msg">{{ error }}</div>{% endfor %}{% endif %}</div><button type="submit">提交表单</button></form></body>
</html>

 

三,测试效果:

页面:

image

接收到的数据:

city: 1
gender: 0
bio: 上海,女