跳到内容

使用数据类

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 自己风格的数据类。

当然,它支持相同的

  • 数据验证
  • 数据序列化
  • 数据文档等。

这与使用 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 playin' and havin' fun",
        "tags": ["breater"],
    }

数据类将自动转换为 Pydantic 数据类。

这样,它的模式就会出现在 API 文档的用户界面中

嵌套数据结构中的数据类

您还可以将 dataclasses 与其他类型注释结合使用以创建嵌套数据结构。

在某些情况下,您可能仍然需要使用 Pydantic 版本的 dataclasses。例如,如果您在自动生成的 API 文档中遇到错误。

在这种情况下,您可以简单地用 pydantic.dataclasses 替换标准的 dataclasses,它是标准 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 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",
                },
            ],
        },
    ]
  1. 我们仍然从标准 dataclasses 中导入 field

  2. pydantic.dataclassesdataclasses 的直接替换。

  3. Author 数据类包含一个 Item 数据类列表。

  4. Author 数据类用作 response_model 参数。

  5. 您可以将其他标准类型注释与数据类一起用作请求体。

    在本例中,它是一个 Item 数据类列表。

  6. 这里我们返回一个包含 items(一个数据类列表)的字典。

    FastAPI 仍然能够 序列化 数据到 JSON。

  7. 这里的 response_model 使用 Author 数据类列表的类型注释。

    同样,您可以将 dataclasses 与标准类型注释结合使用。

  8. 请注意,此 路径操作函数 使用常规的 def 而不是 async def

    与往常一样,在 FastAPI 中,您可以根据需要组合 defasync def

    如果您需要关于何时使用哪个的复习,请查看文档中关于 asyncawait 的部分的 “赶时间?” 部分。

  9. 路径操作函数 不会返回数据类(尽管它可以),而是返回一个包含内部数据的字典列表。

    FastAPI 将使用 response_model 参数(包括数据类)来转换响应。

您可以将 dataclasses 与其他类型注释结合使用以形成各种组合的复杂数据结构。

查看上面的代码内注释提示,了解更具体的细节。

了解更多

您还可以将 dataclasses 与其他 Pydantic 模型结合使用,从它们继承,将它们包含在您自己的模型中等等。

要了解更多信息,请查看 Pydantic 关于数据类的文档

版本

此功能自 FastAPI 版本 0.67.0 开始可用。 🔖