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

如何用FastAPI+Pydantic BaseModel验证解析HTMX表单数据

在FastAPI中用Pydantic BaseModel处理HTMX表单数据

核心结论

完全可以用Pydantic BaseModel定义表单数据结构,不必逐个字段使用Annotated[类型, Form()]的繁琐方式。

可行方案

方案一:自定义依赖项解析表单数据

通过自定义依赖函数,从请求中获取表单数据并映射到BaseModel:

from fastapi import APIRouter, Request, Depends
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel

router = APIRouter()
templates = Jinja2Templates(directory="templates")

# 定义表单数据模型
class FormData(BaseModel):
    testing: str

# 自定义依赖:解析表单数据到模型
async def parse_form_data(request: Request) -> FormData:
    form_data = await request.form()
    # 将ImmutableMultiDict转为字典,传入BaseModel完成验证
    return FormData(**dict(form_data))

@router.post("/post")
async def index_post(request: Request, data: FormData = Depends(parse_form_data)):
    print(data.testing)
    return templates.TemplateResponse("main.html", {'request': request})

方案二:使用Body指定媒体类型

直接通过Body参数指定媒体类型为application/x-www-form-urlencoded,FastAPI会自动将表单数据解析到BaseModel:

from fastapi import APIRouter, Request, Body
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel

router = APIRouter()
templates = Jinja2Templates(directory="templates")

class FormData(BaseModel):
    testing: str

@router.post("/post")
async def index_post(request: Request, data: FormData = Body(..., media_type="application/x-www-form-urlencoded")):
    print(data.testing)
    return templates.TemplateResponse("main.html", {'request': request})

失败原因说明

直接使用Annotated[FormData, Form()]无效,因为Form()是为单个字段设计的,FastAPI无法自动将多字段的表单数据映射到BaseModel实例。上述两种方法分别通过手动解析表单数据、指定正确的媒体类型,解决了映射问题。

HTMX场景适配

HTMX默认发送application/x-www-form-urlencoded格式的请求,上述方案完全适配该场景,无需修改前端代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:55:05