FastAPI
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.8+ 并基于标准的 Python 类型提示。
官方文档:FastAPI (tiangolo.com)
英文文档:FastAPI (tiangolo.com)
本文默认情况:
问题描述
简单来说,无法通过官方推荐的pydantic
来实现用模型类表示来自表单(Form)的字段。
在官方的文档中推荐使用pydantic
的BaseModel
作为请求体的模型类。请求体 - FastAPI (tiangolo.com)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
from fastapi import FastAPI from pydantic import BaseModel
class Student(BaseModel): id: int name: str
app = FastAPI()
@app.post("/student") async def create_student(stu: Student): return stu
|
此时这个请求体中的所有参数都必须来自Body。具体如下图:
如果我们修改Student模型类,增加一个字段,希望这个字段来自Query(即url),会发现不起作用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from fastapi import FastAPI from pydantic import BaseModel
class Student(BaseModel): id: int name: str some_info: str = Query()
app = FastAPI()
@app.post("/student") async def create_student(stu: Student): return stu
|
同理,你也无法通过以下方式表示Student模型类需要来自Form。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from fastapi import FastAPI from pydantic import BaseModel
class Student(BaseModel): id: int name: str
app = FastAPI()
@app.post("/student") async def create_student(stu: Student = Form()): return stu
|
或
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from fastapi import FastAPI from pydantic import BaseModel
class Student(BaseModel): id: int = Form() name: str = Form()
app = FastAPI()
@app.post("/student") async def create_student(stu: Student = Form()): return stu
|
或
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from fastapi import FastAPI, Depends from pydantic import BaseModel
class Student(BaseModel): id: int = Form() name: str = Form()
app = FastAPI()
@app.post("/student") async def create_student(stu: Student = Depends()): return stu
|
解决方法
法1:参照官方文档,不使用模型类
将每个参数单独写在控制器入参中。
表单数据 - FastAPI (tiangolo.com)
Form Data - FastAPI (tiangolo.com)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| from fastapi import FastAPI, Depends from pydantic import BaseModel
app = FastAPI()
@app.post("/student") async def create_student(id: int = Form(), name: str = Form()): return {"id": id, "str": name}
|
法2:用dataclasses
使用数据类 - FastAPI (tiangolo.com)
用dataclasses
下的dataclass
可以代替pydantic
,并且能够实现用模型类定义Form数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from fastapi import FastAPI, Depends from dataclasses import dataclass
@dataclass class Student: id: int = Form() name: str = Form()
app = FastAPI()
@app.post("/student") async def create_student(stu: Student = Depends()): return stu
|
不仅如此,通过在模型类的字段中定义为<变量>: <类型> = Query()
来指定url中的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from fastapi import FastAPI, Depends from dataclasses import dataclass
@dataclass class Student: id: int = Form() name: str = Form() query_info: str = Query()
app = FastAPI()
@app.post("/student") async def create_student(stu: Student = Depends()): return stu
|
另外,关于代码中Depends()
的使用,可以参考文档类作为依赖项 - FastAPI (tiangolo.com) - 快捷方式。在这里一定要加上空的= Depends()
。
类作为依赖项 - FastAPI (tiangolo.com)
[Classes as Dependencies - FastAPI (tiangolo.com)](https://fastapi.tiangolo.com/tutorial/dependencies/classes-as-dependencies/?h= class depe#shortcut)
参考资料
python - How to use a Pydantic model with Form data in FastAPI? - Stack Overflow
FastAPI (tiangolo.com)