使用数据类¶
FastAPI 基于 Pydantic 构建,前文已经介绍过如何使用 Pydantic 模型声明请求与响应。
但 FastAPI 还可以使用数据类(dataclasses
):
from dataclasses import dataclass
from typing import Union
from fastapi import FastAPI
@dataclass
class Item:
name: str
price: float
description: Union[str, None] = None
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
这还是借助于 Pydantic 及其内置的 dataclasses
。
因此,即便上述代码没有显式使用 Pydantic,FastAPI 仍会使用 Pydantic 把标准数据类转换为 Pydantic 数据类(dataclasses
)。
并且,它仍然支持以下功能:
- 数据验证
- 数据序列化
- 数据存档等
数据类的和运作方式与 Pydantic 模型相同。实际上,它的底层使用的也是 Pydantic。
说明
注意,数据类不支持 Pydantic 模型的所有功能。
因此,开发时仍需要使用 Pydantic 模型。
但如果数据类很多,这一技巧能给 FastAPI 开发 Web API 增添不少助力。🤓
response_model
使用数据类¶
在 response_model
参数中使用 dataclasses
:
from dataclasses import dataclass, field
from typing import List, Union
from fastapi import FastAPI
@dataclass
class Item:
name: str
price: float
tags: List[str] = field(default_factory=list)
description: Union[str, None] = None
tax: Union[float, None] = None
app = FastAPI()
@app.get("/items/next", response_model=Item)
async def read_next_item():
return {
"name": "Island In The Moon",
"price": 12.99,
"description": "A place to be be playin' and havin' fun",
"tags": ["breater"],
}
本例把数据类自动转换为 Pydantic 数据类。
API 文档中也会显示相关概图:
在嵌套数据结构中使用数据类¶
您还可以把 dataclasses
与其它类型注解组合在一起,创建嵌套数据结构。
还有一些情况也可以使用 Pydantic 的 dataclasses
。例如,在 API 文档中显示错误。
本例把标准的 dataclasses
直接替换为 pydantic.dataclasses
:
from dataclasses import field # (1)
from typing import List, Union
from fastapi import FastAPI
from pydantic.dataclasses import dataclass # (2)
@dataclass
class Item:
name: str
description: Union[str, None] = None
@dataclass
class Author:
name: str
items: List[Item] = field(default_factory=list) # (3)
app = FastAPI()
@app.post("/authors/{author_id}/items/", response_model=Author) # (4)
async def create_author_items(author_id: str, items: List[Item]): # (5)
return {"name": author_id, "items": items} # (6)
@app.get("/authors/", response_model=List[Author]) # (7)
def get_authors(): # (8)
return [ # (9)
{
"name": "Breaters",
"items": [
{
"name": "Island In The Moon",
"description": "A place to be be playin' and havin' fun",
},
{"name": "Holy Buddies"},
],
},
{
"name": "System of an Up",
"items": [
{
"name": "Salt",
"description": "The kombucha mushroom people's favorite",
},
{"name": "Pad Thai"},
{
"name": "Lonely Night",
"description": "The mostests lonliest nightiest of allest",
},
],
},
]
-
本例依然要从标准的
dataclasses
中导入field
; -
使用
pydantic.dataclasses
直接替换dataclasses
; -
Author
数据类包含Item
数据类列表; -
Author
数据类用于response_model
参数; -
其它带有数据类的标准类型注解也可以作为请求体;
本例使用的是
Item
数据类列表; -
这行代码返回的是包含
items
的字典,items
是数据类列表;FastAPI 仍能把数据序列化为 JSON;
-
这行代码中,
response_model
的类型注解是Author
数据类列表;再一次,可以把
dataclasses
与标准类型注解一起使用; -
注意,路径操作函数使用的是普通函数,不是异步函数;
与往常一样,在 FastAPI 中,可以按需组合普通函数与异步函数;
如果不清楚何时使用异步函数或普通函数,请参阅急不可待?一节中对
async
与await
的说明; -
路径操作函数返回的不是数据类(虽然它可以返回数据类),而是返回内含数据的字典列表;
FastAPI 使用(包含数据类的)
response_model
参数转换响应。
把 dataclasses
与其它类型注解组合在一起,可以组成不同形式的复杂数据结构。
更多内容详见上述代码内的注释。
深入学习¶
您还可以把 dataclasses
与其它 Pydantic 模型组合在一起,继承合并的模型,把它们包含在您自己的模型里。
版本¶
本章内容自 FastAPI 0.67.0
版起生效。🔖