由于某种原因,同时处理
Form
数据和 File
上传会引发错误。
from typing import Annotated
from pydantic import BaseModel, StringConstraints, EmailStr
class RouteBody(BaseModel):
email: Annotated[EmailStr, StringConstraints(
max_length = 255
)]
password: Annotated[str, StringConstraints(
max_length = 60
)]
这强制了路由主体是正确的。超级好看。
from fastapi import UploadFile, File
@some_api_router.post("/some-route")
async def handleRoute(routeBody: RouteBody = Form(), profilePicture: UploadFile = File(...)):
return {"msg": "Route"}
我使用 SwaggerUI 文档对其进行了测试:
我收到以下错误:
error [{'type': 'model_attributes_type', 'loc': ('body', 'routeBody'), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': '{"email":"[email protected]","password":"string"}'}]
要使用带有文件输入的 Pydantic 模型,您只需将该文件包含在 Pydantic 模型本身中。不要向函数添加额外的参数,而是将文件字段直接集成到 Pydantic 模型中。例如,它看起来像这样
class RouteBody(BaseModel):
email: Annotated[EmailStr, StringConstraints(
max_length = 255
)]
password: Annotated[str, StringConstraints(
max_length = 60
)]
image: Annotated[UploadFile, File()]
model_config = {"extra": "forbid"}
@some_api_router.post("/some-route")
async def handleRoute(routeBody: RouteBody = Form()):
return {"msg": "Route"}
在 SwaggerUI 中,您仍然会遇到错误,因为内容类型默认为“application/x-www-form-urlencoded”。为了避免这种情况,切换到 Postman 并将正文类型设置为“form-data”,它应该可以顺利工作。最重要的是所有验证都将正常运行,这是一个很大的优点。这种方法比在函数参数中列出每个必需的输入更好,因为它可以让您一次性定义逻辑,而无需不必要的重复,而且方式更干净。