仅用于验证目的的 pydantic 基本模型"field"



考虑下面的代码,说明使用验证的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_check函数中的values参数是属性的内部字典已经为您的实例验证了,如果您只需要在实例化时检查id_key,而不是在那之后,您可以简单地从values中删除它。

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'

这不是很明确,如果您期望pydanticValidationError,可能会导致应用程序出现问题。您可能需要检查id_key是否确实存在于values中,如果不存在则抛出错误。

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)