コンテンツにスキップ

Body - Fields

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は、残りのすべて(QueryPathBodyなど)のようにfastapiからではなく、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は、QueryPathBodyと同じように機能し、同じパラメータなどをすべて持っています。

「技術詳細」

実際には、QueryPath、および次に示すものは、共通のParamクラスのサブクラスのオブジェクトを作成します。これは、PydanticのFieldInfoクラスのサブクラス自体です。

そして、PydanticのFieldFieldInfoのインスタンスを返します。

BodyFieldInfoのサブクラスのオブジェクトを直接返します。また、後でわかるように、Bodyクラスのサブクラスであるものもいくつかあります。

fastapiからQueryPathなどをインポートすると、実際には特別なクラスを返す関数であることに注意してください。

ヒント

型、デフォルト値、Fieldを持つ各モデルの属性が、パス操作関数のパラメータと同じ構造をしていることに注意してください。PathQueryBodyの代わりにFieldを使用します。

追加情報を加える

FieldQueryBodyなどで追加情報を宣言できます。そして、それは生成されたJSONスキーマに含まれます。

例を宣言することを学ぶときに、ドキュメントの後半で追加情報を加えることについて詳しく学びます。

注意

Fieldに渡された追加のキーは、アプリケーションのOpenAPIスキーマにも存在します。これらのキーは必ずしもOpenAPI仕様の一部ではない可能性があるため、OpenAPIバリデーターなどの一部のOpenAPIツールは、生成されたスキーマでは機能しない場合があります。

まとめ

PydanticのFieldを使用して、モデル属性の追加の検証とメタデータを宣言できます。

また、追加のキーワード引数を使用して、追加のJSONスキーマメタデータを渡すこともできます。