跳至內容

Body - 欄位

如同您可以使用 QueryPathBody路徑操作函式參數中宣告額外的驗證和中繼資料一樣,您也可以使用 Pydantic 的 Field 在 Pydantic 模型內宣告驗證和中繼資料。

匯入 Field

首先,您必須匯入它

from typing import Annotated

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: float | None = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
    results = {"item_id": item_id, "item": item}
    return results
from typing import Annotated, Union

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: Union[float, None] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
    results = {"item_id": item_id, "item": item}
    return results
from typing import Union

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field
from typing_extensions import Annotated

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: Union[float, None] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
    results = {"item_id": item_id, "item": item}
    return results

提示

如果可以,建議使用 Annotated 版本。

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: float | None = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

提示

如果可以,建議使用 Annotated 版本。

from typing import Union

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: Union[float, None] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

警告

請注意,Field 是直接從 pydantic 匯入的,而不是像其他所有函式 (QueryPathBody 等) 一樣從 fastapi 匯入。

宣告模型屬性

然後您可以將 Field 與模型屬性一起使用

from typing import Annotated

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: float | None = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
    results = {"item_id": item_id, "item": item}
    return results
from typing import Annotated, Union

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: Union[float, None] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
    results = {"item_id": item_id, "item": item}
    return results
from typing import Union

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field
from typing_extensions import Annotated

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: Union[float, None] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
    results = {"item_id": item_id, "item": item}
    return results

提示

如果可以,建議使用 Annotated 版本。

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: float | None = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

提示

如果可以,建議使用 Annotated 版本。

from typing import Union

from fastapi import Body, FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = Field(
        default=None, title="The description of the item", max_length=300
    )
    price: float = Field(gt=0, description="The price must be greater than zero")
    tax: Union[float, None] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

Field 的工作方式與 QueryPathBody 相同,它具有所有相同的參數等等。

「技術細節」

實際上,QueryPath 和您接下來會看到的其他函式會建立一個共同 Param 類別的子類別物件,而該類別本身又是 Pydantic 的 FieldInfo 類別的子類別。

而 Pydantic 的 Field 也會返回一個 FieldInfo 的實例。

Body 也會直接返回 FieldInfo 子類別的物件。而您稍後會看到其他 Body 類別的子類別。

請記住,當您從 fastapi 匯入 QueryPath 和其他函式時,這些實際上是返回特殊類別的函式。

提示

請注意,每個具有類型、預設值和 Field 的模型屬性都與路徑操作函式的參數具有相同的結構,只是使用 Field 而不是 PathQueryBody

新增額外資訊

您可以在 FieldQueryBody 等中宣告額外資訊。這些資訊將包含在產生的 JSON Schema 中。

在稍後的文件中,您將在學習宣告範例時瞭解更多關於新增額外資訊的內容。

警告

傳遞給 Field 的額外鍵值也會出現在應用程式的結果 OpenAPI 結構描述中。由於這些鍵值可能不一定是 OpenAPI 規範的一部分,因此某些 OpenAPI 工具,例如 OpenAPI 驗證器,可能無法與您產生的結構描述一起使用。

摘要

您可以使用 Pydantic 的 Field 來宣告模型屬性的額外驗證和中繼資料。

您也可以使用額外的關鍵字引數來傳遞額外的 JSON Schema 中繼資料。