FastApi学习第二天:Pydantic对数据的校验和Form表单数据
Pydantic对数据的校验
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,它使用 Python 3.6+ 版本。FastAPI 利用 Python 类型提示来自动生成文档,并且支持异步请求处理。FastAPI 与 Pydantic 结合使用,可以提供强大的数据校验功能。Pydantic 是一个数据验证和设置管理的库,它使用 Python 类型注解来验证输入数据。
在 FastAPI 中,Pydantic 数据校验主要通过以下几个方面实现:
-
使用 Pydantic 模型:你可以定义一个 Pydantic 模型(继承自
BaseModel
),在模型中声明数据字段及其类型,Pydantic 会自动校验传入的数据是否符合这些类型和字段要求。例如:
from pydantic import BaseModel class Item(BaseModel): name: str description: str = None price: float tax: float = None
在这个例子中,
name
和price
是必须的字段,description
是可选的字符串字段,默认为None
,tax
也是一个可选的浮点数字段,默认为None
。如果传入的数据不符合这些要求,FastAPI 会返回一个错误响应。 -
路径参数和查询参数:FastAPI 允许你在路径操作函数中使用类型注解来定义路径参数和查询参数,Pydantic 会自动进行校验。例如:
from fastapi import FastAPI, Path, Query app = FastAPI() @app.get("/items/{item_id}") def read_item(item_id: int = Path(..., description="The ID of the item")): return {"item_id": item_id}
在这个例子中,
item_id
是一个路径参数,必须为整数,Pydantic 会校验传入的item_id
是否为整数。 -
请求体:FastAPI 允许你在路径操作函数中使用 Pydantic 模型作为请求体参数,Pydantic 会自动校验请求体数据。例如:
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str description: str = None price: float tax: float = None @app.post("/items/") def create_item(item: Item): return item
在这个例子中,客户端需要发送一个 JSON 请求体,其结构必须与
Item
模型相匹配,否则会返回错误。 -
响应模型:你可以使用 Pydantic 模型作为响应模型,FastAPI 会自动序列化模型实例为 JSON 响应体,并进行校验。例如:
@app.get("/items/{item_id}", response_model=Item) def read_item(item_id: int, item: Item = Depends(get_item)): return item
在这个例子中,
response_model=Item
指定了响应模型,FastAPI 会确保响应体符合Item
模型的结构。
FastAPI 和 Pydantic 的结合使得数据校验变得非常简单和强大,它们自动处理了很多繁琐的数据校验工作,让你可以更专注于业务逻辑的实现。通过自动生成的文档(访问 /docs
路径),开发者和用户可以清晰地了解 API 的使用方式和数据要求。
FastAPI 中使用表单(form)提交的数据
在 FastAPI 中,使用表单(form)提交的数据可以通过 Form
类型来处理。FastAPI 支持多种表单数据的提交方式,包括普通的文本表单、文件上传表单以及复杂的嵌套表单。
1. 简单表单参数
如果你的表单只包含简单的文本字段,你可以通过 Form
来获取这些字段的值。
示例:提交用户名和密码
表单 HTML:
<form action="/login" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Login</button>
</form>
FastAPI 代码:
from fastapi import FastAPI, Form
app = FastAPI()
@app.post("/login")
async def login(username: str = Form(...), password: str = Form(...)):
return {"username": username, "password": password}
在这个例子中,username
和 password
是通过表单提交的字段,FastAPI 使用 Form
来自动解析它们。
2. 表单参数类型验证
你可以在 Form
中使用 FastAPI 提供的类型验证功能。FastAPI 会根据你声明的类型自动验证传入的表单数据。
示例:限制用户名的长度
from fastapi import FastAPI, Form
from pydantic import constr
app = FastAPI()
@app.post("/signup")
async def signup(username: constr(min_length=3, max_length=20) = Form(...), password: str = Form(...)):
return {"username": username, "password": password}
这里 username
限制了长度范围,FastAPI 会自动检查传入的表单数据是否符合限制。
3. 可选表单参数
如果你希望某些表单字段是可选的,可以给 Form
中的字段指定默认值 None
。
示例:可选的邮箱字段
from fastapi import FastAPI, Form
from typing import Optional
app = FastAPI()
@app.post("/register")
async def register(username: str = Form(...), email: Optional[str] = Form(None)):
return {"username": username, "email": email}
如果提交表单时没有填写 email
字段,FastAPI 会将其设置为 None
。
4. 处理文件上传
FastAPI 还支持通过表单提交文件。要处理文件上传,需要使用 File
来处理文件字段,配合 Form
处理其他文本字段。
示例:提交头像图片
from fastapi import FastAPI, File, Form
app = FastAPI()
@app.post("/upload_avatar")
async def upload_avatar(username: str = Form(...), file: UploadFile = File(...)):
content = await file.read()
return {"username": username, "file_size": len(content)}
在这个例子中,file
是通过 File
来接收上传的文件,username
依旧是通过 Form
来接收表单数据。
5. 表单嵌套(复杂表单)
如果你需要处理一个嵌套的表单数据(例如一个对象里面包含多个字段),可以使用 Pydantic 模型来处理。
示例:嵌套表单
假设你有一个包含多个字段的表单,如下:
HTML 表单:
<form action="/create_item" method="post">
<input type="text" name="item_name" placeholder="Item Name">
<input type="number" name="price" placeholder="Price">
<input type="text" name="category" placeholder="Category">
<button type="submit">Create Item</button>
</form>
你可以通过 Pydantic 模型来封装表单数据:
from fastapi import FastAPI, Form
from pydantic import BaseModel
class Item(BaseModel):
item_name: str
price: float
category: str
app = FastAPI()
@app.post("/create_item")
async def create_item(item: Item):
return {"item_name": item.item_name, "price": item.price, "category": item.category}
在这里,Item
模型会自动将表单字段映射到相应的字段,FastAPI 会根据表单数据的字段名来填充这个模型。
6. 使用表单参数和路径参数
你可以同时使用路径参数和表单参数。比如:
示例:同时使用路径参数和表单参数
from fastapi import FastAPI, Form
app = FastAPI()
@app.post("/update_item/{item_id}")
async def update_item(item_id: int, item_name: str = Form(...), price: float = Form(...)):
return {"item_id": item_id, "item_name": item_name, "price": price}
在这个例子中,item_id
是路径参数,而 item_name
和 price
是表单参数。
总结
FastAPI 对表单参数的处理非常灵活,可以让你轻松处理文本字段、文件上传、以及复杂的嵌套表单数据。你只需要配合 Form
、File
、UploadFile
和 Pydantic 模型就可以构建出各种类型的表单接口。