美文网首页
basic usage of lib pydantic for

basic usage of lib pydantic for

作者: 9_SooHyun | 来源:发表于2023-04-23 16:42 被阅读0次
from pydantic import BaseModel, Field, validator

# -----基本model定义-----

# 1.


class User(BaseModel):
    """
    simple data model: User
    """
    name : str  # no default value means must give value
    age: int  # ... must give value


# 2. 基于pydantic的collection
from pydantic_collections import BaseCollectionModel


class UserCollection(BaseCollectionModel[User]):
    """
    定义了User列表 的 data model,这样可以直接使用.dict()
    """
    pass

# 3.


class UserContainer(BaseModel):
    """
    BaseCollectionModel作为其他model的成员字段
    """
    all_users : UserCollection = Field(None)


# --------以下测试---------
def pydantic_basic_usage():
    single_user = User(name="hh", age=12)

    # model to dict
    d_data = single_user.dict()
    # dict to model
    single_user = User.parse_obj(d_data)

    # take User into a list
    l_user = [single_user]
    f = f"user list format: {l_user}"
    print(f)  # user list format: [TestModel(name='hh', age=12)]。注意,这里不能l_user.dict(),因为l_user是list,没有dict方法


def pydantic_collections_usage():
    user_data = [
        {'name': 'Bender', 'age': 10},
        {'name': 'Balaganov', 'age': 12},
    ]
    # init an UserCollection
    users = UserCollection(user_data)

    # append an user to UserCollection
    single_user = User(name="hh", age=12)
    users.append(single_user)  # ok
    # users.append(user_data[0]) # failed. instance of User expected (type=type_error.arbitrary_type; expected_arbitrary_type=User)
    print(users.dict(), users.json())


def pydantic_container_usage():
    data = {
        "all_users": [
            {'name': 'Bender', 'age': 10},
            {'name': 'Balaganov', 'age': 12},
        ]
    }

    container = UserContainer(**data)
    print(container.dict())


def pydantic_validator_usage():
    class UserWithValidator(BaseModel):
        name : str = Field(None)
        age : int = Field(None)

        @validator("age")
        def num_check(cls, v):
            """
            v 表示 age 对应的值
            """
            print("enter validator num_check")
            if v < 0:
                v = 0
            if v > 100:
                v = 100
            # validate and modify
            return v

        @validator("name")
        def lenth_check(cls, v):
            """
            v 表示 name 对应的值
            """
            print("enter validator lenth_check")
            if len(v) > 6:
                v = v[:6]
            # validate and modify
            return v

        @validator("age", "name", pre=True)
        def not_none(cls, v):
            """
            必须全部赋值,不可为None
            该 validator 在目标作用字段的其他所有validator之前执行
            """
            print("enter validator not_none")
            if v is None:
                raise ValueError("None value exists")
            return v

        @validator("age")
        def change_age_for_user_hhhhhh(cls, v, values):
            """
            values:包含任何先前验证字段的名称到值映射的字典
            修改用户hhhhhh的年龄为15岁
            """
            print("enter validator change_age_for_user_hhhhhh")
            user_name = values["name"]
            if user_name == "hhhhhh":
                v = 15
            return v


    single_user = UserWithValidator(name="hhhhhhhhh", age=-10)
    print(single_user.dict())
    # output:
    # enter validator not_none
    # enter validator lenth_check   -> 到此都是check field 'name'
    # enter validator not_none
    # enter validator num_check
    # enter validator change_age_for_user_hhhhhh   -> 到此都是check field 'age'
    # {'name': 'hhhhhh', 'age': 15}
    # 可以看到,validator的执行顺序是:
    # 1. 字段顺序优先,validator定义顺序优先
    # 2. 我们可以给validator传递pre=True,让它在目标作用字段的其他所有validator之前执行


if __name__ == "__main__":
    pydantic_basic_usage()
    pydantic_collections_usage()
    pydantic_container_usage()
    pydantic_validator_usage()

相关文章

网友评论

      本文标题:basic usage of lib pydantic for

      本文链接:https://www.haomeiwen.com/subject/pclyjdtx.html