FastAPI 表单模型:使用 Pydantic 模型声明和禁用多余的表单字段
在 FastAPI 中,可以通过 Pydantic 模型来声明和禁用多余的表单字段。本文介绍了如何使用 Pydantic 的 BaseModel
来定义包含表单字段的模型,并通过 Form
自动提取请求中的表单数据并进行映射。此外,文章还讲解了如何使用 Pydantic 配置来限制表单字段,并禁用未声明的多余字段,从而提高数据的安全性和可靠性。最后,展示了如何使用 Form
函数和模型结合,实现更灵活的表单数据处理。
可以通过 Pydantic 模型在 FastAPI 中声明表单字段。以下示例中使用的 Python 版本为 Python 3.10.15
,FastAPI 版本为 0.115.4
。
一 Pydantic 模型支持表单
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: FormData = Form()):
return data
只需声明一个包含所需表单字段的 Pydantic 模型,并将参数指定为 Form
即可,FastAPI 会从请求中的表单数据提取各字段的值,并自动映射到定义的 Pydantic 模型。运行代码文件 chapter19.py 来启动应用:
$ uvicorn chapter19:app --reload
在 SwaggerUI 中可以查看在线文档:http://127.0.0.1:8000/docs
。
注:使用表单需预先安装 python-multipart
,pip install python-multipart
。
二 禁用多余字段
如果想将表单字段限制为仅包含在 Pydantic 模型中声明的字段,并禁止其他多余字段,则可通过 Pydantic 模型配置 {"extra": "forbid"}
实现。
class FormData01(BaseModel):
username: str
password: str
model_config = {"extra": "forbid"}
@app.post("/login01/")
async def login01(data: FormData01 = Form()):
return data
如果客户端尝试发送其他未定义的多余数据,将收到错误响应。例如:
POST /login01 HTTP/1.1
Accept: */*
Accept-Encoding: deflate, gzip
User-Agent: Mozilla/5.0 AppleWebKit/537.00
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 47
username=hello&password=world&yourapi=haha
将收到一条错误响应并指出多余字段 yourapi
不被允许。
{
"detail": [{
"type": "extra_forbidden",
"loc": ["body", "yourapi"],
"msg": "Extra inputs are not permitted",
"input": "haha"
}]
}
三 其他用法
@app.post("/login02/")
async def login(username: str = Form(...), password: str = Form(...)):
form_data = FormData(username=username, password=password)
return form_data
通过 Form
函数将表单字段映射为函数参数,并使用 FormData
类封装表单数据,最终返回一个 form_data
对象。
四 完整代码示例
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class FormData(BaseModel):
username: str
password: str
class FormData01(BaseModel):
username: str
password: str
model_config = {"extra": "forbid"}
@app.post("/login/")
async def login(data: FormData = Form()):
return data
@app.post("/login01/")
async def login01(data: FormData01 = Form()):
return data
@app.post("/login02/")
async def login(username: str = Form(...), password: str = Form(...)):
form_data = FormData(username=username, password=password)
return form_data
五 源码地址
六 参考
[1] FastAPI 文档