跳至內容

使用資料類別

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 網路 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 資料類別。

這樣,它的 Schema 就會顯示在 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 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 有關 dataclasses 的文件

版本

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