Fastapiにてvalidationをschemaに追加したい

Web開発

皆さん、こんにちは!

fastapiを触っている途中で、思ったことなのですが。

なんで、pydanticを内部で使用しているのに、schema内でvalidationは使わないのかと。

今回はそれについて書きます。

Fastapiにおけるschema内でのvalidation

Googleで調べていると、普通にその件についての記事が以下に書いてありました。

[QUESTION] Why not introduce pydantic @validator in docs?

結論から、先に書くと。

単にfastapiのサイトに乗せていないだけのようです。

そのため、普通に使っていいかと。

以下、参考程度に書いておきます。

この前の記事でEnumを使用したので、今回はEnumで定義したものかどうかを確認するvalidationを用意してみましょう。

from typing import Optional, Union
from pydantic import BaseModel, Field, validator
from models.user import UserType


class UserBase(BaseModel):
    role: Optional[str] = Field(title="User role")
    name: Optional[str] = Field(title="User name")

    @validator("role")
    def check_user_role(cls, v: str) -> Union[str, ValueError]:
        roles = [name for name, _ in UserType.__members__.items()]
        if v not in roles:
            raise ValueError("User role should be either of " + ", ".join(roles))
        return v

 
class UserCreate(UserBase):
    role: str = Field(title="User role")
    name: str = Field(title="User name", max_length=100)


class UserUpdate(UserBase):
    pass


class UserInDBBase(UserBase):
    class Config:
        orm_mode = True


class User(UserInDBBase):
    id: int = Field(title="User ID")
    role: str = Field(title="User role")
    name: str = Field(title="User name")


class UserInDB(UserInDBBase):
    pass

validatorデコレータに、対象のカラムを指定します。

今回は、ユーザロールに対してvalidationをかけたいので、roleカラムを指定してます。

もし、モデルで定義したUserTypeに含まれていないものがroleに入った場合に、はじくようにしてます。

@validator("role")
def check_user_role(cls, v: str) -> Union[str, ValueError]:
    roles = [name for name, _ in UserType.__members__.items()]
    if v not in roles:
        raise ValueError("User role should be either of " + ", ".join(roles))
    return v

モデルで定義したEnumのメンバー名のみ取得したいので、☝で書いているように。 UserType.__members__.items()でtapleを取得したあとに、nameのみをリストにいれるようにしてます。

参考

[QUESTION] Why not introduce pydantic @validator in docs? · Issue #312 · tiangolo/fastapi
Description I am new to fastapi and web APIs in general, but found it astonishing simple and fast to create a first working api. In the process, I found using p...
enum — Support for enumerations — Python 3.8.6 documentation
タイトルとURLをコピーしました