当前位置: 首页 > news >正文

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: 上海,女

 

http://www.jsqmd.com/news/1270214/

相关文章:

  • AI移动端UI设计避坑指南(2024年iOS/Android双平台实测失效模式全曝光)
  • HarmonyOS应用《玄象》开发实战:GreatWheelPage 卦象大轮盘:极坐标布局与旋转手势
  • Python 高级编程实战:collections、并发与 Redis
  • 基于MA-DQL的无人机通信网络优化实践
  • 2026毕业论文写作技巧工具深度横评,学范文领衔五强避坑指南
  • 基于OpenCV的身份证号码识别优化方案
  • 2026年7月浙江省金华市电信300M融合宽带小白避坑指南 - 找卡家园
  • 国内玻璃圆盘检测机厂家实力排行:精度与产能双维度对比 - 互联网科技品牌测评
  • 考试精华:系统架构设计师核心概念汇总(七)
  • 点到点ICP-基于SVD分解的帧间点云匹配
  • 【提示词工程黄金模板】:20年资深工程师私藏的5大代码解释模板,90%开发者从未见过
  • 【AI数字人虚拟看房实战指南】:2024年房企降本增效的5大落地场景与3个避坑红线
  • 垃圾焚烧发电智能控制系统:数字孪生与强化学习的应用
  • Unlock-Music技术深度解析:浏览器端音乐解密实战指南
  • 2026年广东工业连接器与汽车电子连接器:专业厂家的选择与行业格局 - 卓企推荐
  • M9A终极指南:3步实现重返未来1999自动化游戏
  • Firebase赋能deliverzler:构建实时数据同步的外卖配送系统
  • 2026年毕业论文写作工具排行榜:学范文等五家降重查重实测对比
  • 多模态MRI重建:深度学习与物理模型融合的创新方案
  • 2026年7月浙江省金华市电信1000M融合宽带怎么安装? - 找卡家园
  • 福建夏季高考复读机构评测:综合维度对比一览 - 互联网科技品牌测评
  • MockBukkit完全指南:如何为Bukkit插件编写高效单元测试
  • 仅限内部流出:某顶级AI研究院创意题测试题库逆向分析报告(含3类稀缺性干扰项识别图谱)
  • tsc-watch完全指南:TypeScript开发的终极热重载工具
  • 2026年7月河北省廊坊市联通宽带办理与避坑全攻略 - 找卡家园
  • HarmonyOS应用《玄象》开发实战:底部导航栏 BottomTabBar 封装与 @Builder 复用
  • 移动端协议逆向:从抓包到还原加密通信的全流程
  • Python深度学习实战:YOLOv5智能宠物识别系统
  • 3步搭建Streetmix本地开发环境:开发者入门教程
  • 抖音下载器终极指南:5步实现无水印批量下载与智能管理