【问题标题】:Pydantic. How to add data alteration functions within the class狡猾的。如何在类中添加数据更改功能
【发布时间】:2021-07-19 03:30:01
【问题描述】:

我刚刚开始学习 Pydantic 和 FastAPI。我的模型看起来像这样。

class Max70Text(BaseModel):
    __root__: constr(min_length=1,max_length=70) = Field(
        ...,
        description='Specifies a character string with a maximum length of 70 characters.'    
    )

如果我的字符串长度超过 70,我会在我的主程序中处理此类之外的截断函数。 我想在课堂上这样做只是为了保持干净。 IE。如果将长度超过 70 的字符串传递给此类,则返回的对象应自动从右侧截断其 str 值以匹配长度。

【问题讨论】:

  • 使用验证器函数并截断那里的转向。
  • 在这种情况下使用验证器的重要一点:您需要添加pre=True,以便在检查max_length 之前进行验证。

标签: python fastapi pydantic


【解决方案1】:

您可以使用root_validator 根据您的限制解析传入的数据:

class Max70Text(BaseModel):
    __root__: constr(min_length=1,max_length=70) = Field(
        ...,
        description='Specifies a character string with a maximum length of 70 characters.'
    )

    @staticmethod
    def truncate(v):
        return v[:70]

    @root_validator(pre=True)
    def len_validator(cls, values):
        values['__root__'] = cls.truncate(values['__root__'])
        return values

除了上面的root types之外,pydantic还允许你创建自己的custom data types,在某些情况下更方便。演示尚未准备好生产:

from pydantic import BaseModel, Field


class TruncatedBase(str):
    limit: int

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)

    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def truncate(cls, value: str):
        return value[:cls.limit] + "..." if len(value) > cls.limit else value

    @classmethod
    def validate(cls, v):
        if not isinstance(v, str):
            raise TypeError('string required')
        if not v:
            raise TypeError('empty string is not allowed')
        return cls(cls.truncate(v))

    def __repr__(self):
        return f'Max{self.limit}Text({super().__repr__()})'


def truncated_text(limit=10):
    return type('TruncatedText', (TruncatedBase,), {'limit': limit})


class Model(BaseModel):
    field1: truncated_text(limit=5) = Field(..., description="5 max")
    field2: truncated_text(limit=6) = Field(..., description="6 max")


print(Model(field1="1"*6, field2="1"*6))

输出:

field1=Max5Text('11111...') field2=Max6Text('111111')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2011-01-19
    相关资源
    最近更新 更多