FastAPI 表单模型实战用 Pydantic 模型声明与校验表单字段【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi本篇基于 FastAPI 官方教程文档《Formularmodelle表单模型》讲解如何在 FastAPI 中直接使用Pydantic 模型来声明表单字段form fields从安装依赖、声明Form参数、自动从请求中提取并校验各字段到通过extra forbid禁止客户端提交模型中未声明的额外字段。读完后你将掌握这套自 FastAPI0.113.0起支持的表单建模能力并理解其在 OpenAPI 文档生成与请求校验中的底层实现0.114.0 起额外支持禁止额外字段。前置条件安装 python-multipart使用表单功能的第一步是安装python-multipart包。将其添加到你的项目中$ uv add python-multipart这个依赖在 FastAPI 内部是被硬性检查的。从源码看fastapi/dependencies/utils.py 中定义了专门的错误提示与检查函数ensure_multipart_is_installed()它尝试导入python_multipart并断言版本大于0.0.12若导入失败或版本过低则抛出RuntimeError提示安装python-multipart甚至针对误装了名为multipart而非python-multipart的包的情况也准备了单独的提示multipart_incorrect_install_error。所以遇到 Form data requires python-multipart 报错时检查包名和版本是第一排查方向。版本前提说明使用 Pydantic 模型声明表单字段自 FastAPI0.113.0起支持通过extra: forbid禁止额外表单字段自 FastAPI0.114.0起支持。用 Pydantic 模型声明表单字段你只需声明一个包含所有期望接收的表单字段的Pydantic 模型然后把路径操作函数中的参数声明为Form即可。完整可运行示例对应 docs_src/request_form_models/tutorial001_an_py310.pyfrom typing import Annotated from fastapi import FastAPI, Form from pydantic import BaseModel app FastAPI() class FormData(BaseModel): username: str password: str app.post(/login/) async def login(data: Annotated[FormData, Form()]): return dataFastAPI会从请求的表单数据中提取每个字段的数据完成 Pydantic 校验后把定义好的 Pydantic 模型实例传递给你的端点函数。底层实现Form 继承自 Body从源码结构看Form在 fastapi/params.py 中定义为class Form(Body)即表单参数在内部被当作一种特殊的 Body 参数处理。其构造函数签名为class Form(Body): def __init__( self, default: Any Undefined, *, default_factory: Callable[[], Any] | None _Unset, annotation: Any | None None, media_type: str application/x-www-form-urlencoded, alias: str | None None, # ... 以及 gt/ge/lt/le、min_length/max_length、pattern、discriminator、strict 等 )关键点是默认media_type为application/x-www-form-urlencoded——这意味着默认的表单模型端点接收的是 URL 编码的表单数据浏览器form默认提交格式而不是multipart/form-data文件上传格式。参数解析完成后FastAPI 按模型定义逐字段提取并校验最终端点拿到的是类型化的FormData实例而不是原始字典。在 /docs 界面验证你可以在/docs的文档 UI 中直接测试该端点见文首截图。OpenAPI Schema 会正确生成表单请求体。测试用例 tests/test_tutorial/test_request_form_models/test_tutorial001.py 中的test_openapi_schema断言了生成的 Schema 结构核心片段如下{ requestBody: { content: { application/x-www-form-urlencoded: { schema: {$ref: #/components/schemas/FormData} } }, required: true } }可以看到请求体以application/x-www-form-urlencoded为 content typeSchema 通过$ref指向组件区中的FormData模型定义且标记为required: true。组件区中FormData的定义为{ FormData: { properties: { username: {type: string, title: Username}, password: {type: string, title: Password} }, type: object, required: [username, password], title: FormData } }这意味着 API 客户端可以基于 OpenAPI 规范自动生成表单请求代码字段类型与必填约束都来自你的 Pydantic 模型。校验行为缺字段与内容类型不符都会得到 422同一测试文件还验证了多种失败场景对实际联调很有参考价值请求方式结果POST /login/data{username: Foo, password: secret}200返回{username: Foo, password: secret}缺少password字段422type: missingloc: [body, password]msg: Field required缺少username字段422type: missingloc: [body, username]完全不携带数据422两个字段均报missing以 JSON 方式发送json{...}而非表单数据422两个字段均报missing最后一条值得特别注意如果客户端用 JSON 而不是表单编码发送数据FastAPI 无法从表单数据中提取到任何字段会以字段缺失的方式返回422校验错误而不是成功接收。禁止额外的表单字段在某些特殊使用场景可能并不常见下你希望将表单字段限制为 Pydantic 模型中声明的那些字段并禁止任何额外字段。此能力自 FastAPI0.114.0起支持。方法是通过 Pydantic 的模型配置将extra字段设置为forbid对应 docs_src/request_form_models/tutorial002_an_py310.pyclass FormData(BaseModel): username: str password: str model_config {extra: forbid}如果客户端尝试提交额外数据会收到一个错误响应。例如客户端尝试发送以下表单字段username:Rickpassword:Portal Gunextra:Mr. Poopybutthole它将收到一个提示extra字段不被允许的 Error 响应{ detail: [ { type: extra_forbidden, loc: [body, extra], msg: Extra inputs are not permitted, input: Mr. Poopybutthole } ] }源码与测试印证extra forbid的影响体现在两个层面均可在仓库中找到证据运行时校验tests/test_tutorial/test_request_form_models/test_tutorial002.py 中的test_post_body_extra_form用data{username: Foo, password: secret, extra: extra}发起请求断言返回422且detail中为type: extra_forbidden、loc: [body, extra]的校验错误——与上文文档给出的错误响应结构完全一致。OpenAPI Schema 同步更新test_tutorial002.py中的test_openapi_schema断言生成的FormDataSchema 中额外出现了additionalProperties: falsetutorial001 的对应 Schema 中没有这一项。也就是说extra forbid不仅影响运行时行为还会反映到对外发布的 API 契约中让 API 消费方能明确感知不允许额外字段。从源码结构看这一行为源自 Pydantic 模型配置与 FastAPI 表单参数解析的结合Form参数在内部走 Body 参数流程见 fastapi/params.py 中Form(Body)的定义而 Pydantic 模型自身的model_config会原样参与实例化与 Schema 导出因此无需 FastAPI 侧做特殊处理即可同时作用于校验与文档生成。总结你只需要声明一个包含期望表单字段的Pydantic 模型并把参数标记为Form()FastAPI 就会自动从请求的表单数据中逐字段提取并校验然后把模型实例交给端点函数FastAPI0.113.0表单功能依赖python-multipart包FastAPI 内部通过ensure_multipart_is_installed()强制检查该依赖Form参数默认以application/x-www-form-urlencoded接收数据OpenAPI 文档会自动生成对应的必填请求体 Schema便于 API 文档展示与客户端代码生成通过model_config {extra: forbid}可以禁止客户端提交模型之外的额外表单字段触发extra_forbidden校验错误并同步在 OpenAPI Schema 中标记additionalProperties: falseFastAPI0.114.0相关示例代码见 docs_src/request_form_models/ 目录回归测试见 tests/test_tutorial/test_request_form_models/ 目录可对照源码验证上述全部行为。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考