Pydantic BaseModel中的“field”仅用于验证目的。

3

考虑以下代码,演示了使用pydanticBaseModel进行验证:

from pydantic import BaseModel, validator

class User(BaseModel, frozen=True):
    id_key: int
    user_id: int

    @validator('user_id')
    def id_check(cls, v, values):
        if v > 2 * values['id_key'] + 1:
            raise ValueError('id check failed.')
        return v

user_dict = {'user_id': 10, 'id_key': 60}
u = User(**user_dict)

现在,在我的应用程序中,我并不希望id_key成为像u那样的常规可访问字段--它唯一的目的是验证user_id。 对于我的示例,有没有一种方式可以访问id_key以进行验证,但不使其成为标准字段?


使用两个类怎么样?一个带有“id_key”用于执行验证,另一个不带“id_key”,当您知道数据可信时可以使用。带有“id_key”的类可以从另一个类继承,并实现所需的任何其他验证。 - Hernán Alarcón
1个回答

2
你的 id_check 函数中的 values 参数是你实例已经验证过的内部属性字典。如果你只需要在实例化时检查 id_key,而不是在此之后的时间进行检查,那么你可以从 values 中简单地删除它。请注意保留 HTML 标签。
from pydantic import BaseModel, validator

class User(BaseModel, frozen=True):
    id_key: int
    user_id: int

    @validator('user_id')
    def id_check(cls, v, values):
        if v > 2 * values['id_key'] + 1:
            raise ValueError('id check failed.')
        values.pop('id_key')
        return v

user_dict = {'user_id': 10, 'id_key': 60}
u = User(**user_dict)
print(u)
# output:
# user_id=10

我有一个关于你的代码的建议:目前的状态是,当pydantic在返回验证错误之前运行所有字段的验证时,如果你传递了完全无效的id_key,例如"abc",或者省略它,它将不会添加到values中,并且user_id的验证将崩溃并显示KeyError: 'id_key',导致所有其他验证过程被忽略,没有返回任何有意义的消息。因此,我建议进行一些改进。

user_dict = {'user_id': 10, 'id_key': 'abc'}
u = User(**user_dict)
# output:
# KeyError: 'id_key'

这并不是很明确,如果你期望一个pydantic的ValidationError,那么可能会导致应用程序出现问题。你可能想要检查values中是否确实存在id_key,如果不存在,则干净地引发错误。

from pydantic import BaseModel, validator

class User(BaseModel, frozen=True):
    id_key: int
    user_id: int

    @validator('user_id')
    def id_check(cls, v, values):
        if 'id_key' not in values or v > 2 * values['id_key'] + 1:
            raise ValueError('id check failed.')
        values.pop('id_key')
        return v

user_dict = {'user_id': 10, 'id_key': 'abc'}
u = User(**user_dict)
# output:
# pydantic.error_wrappers.ValidationError: 2 validation errors for User
# id_key
#   value is not a valid integer (type=type_error.integer)
# user_id
#   id check failed.(type=value_error)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接