[英]How to get json of model pydantic in validator function
想象一下,我有像这样的 pydantic 的 Model:
class Input(BaseModel): field1: ObjectIdField =... field2: str =... field3: int =... field4: str =... @validator('field4') def validate_field4(cls, v, values, **kwargs): # print(values) => {'field1': ObjectId('63185d5c721c6ef40eb2462a'), 'field2': 'deleted', 'field3': 1} # I want to check this # if json.dumps(values) == v: # OK # else: # raise Exception return v class Config: json_encoders = { ObjectId: lambda v: str(v), }
如您所见,我想获得 model 的 json 除了一个字段(字段4)。 有没有很好的解决方案来处理 model 的内部验证器?
评论未能解决的是 Pydantics .json
是一个实例方法(就像.dict
方法一样),因此在验证器中完全没用,验证器始终是在实例初始化之前调用的class方法。
(注意:您没有提供有关您的ObjectIdField
class 如何工作的代码或解释,因此我不得不猜测并实现一个非常简单的 class 来尝试模拟您显示的行为。)
这是完成验证的一种方法:
import json
from typing import Any
from pydantic import BaseModel, validator
class ObjectIdField:
def __init__(self, value: str) -> None:
self.value = value
def __repr__(self) -> str:
return f"ObjectId('{self.value}')"
def __str__(self) -> str:
return self.value
def encode_obj_id(obj_id: ObjectIdField) -> str:
return str(obj_id)
def json_encode(obj: Any) -> str:
return json.dumps(obj, default=encode_obj_id)
class Input(BaseModel):
field1: ObjectIdField = ...
field2: str = ...
field3: int = ...
field4: str = ...
@validator('field4')
def validate_field4(cls, v: str, values: dict[str, Any]) -> str:
serialized = json_encode(values)
assert v == serialized
return v
class Config:
arbitrary_types_allowed = True # to allow `ObjectIdField`
json_encoders = {
ObjectIdField: encode_obj_id,
}
if __name__ == '__main__':
data = dict(
field1=ObjectIdField("abc"),
field2="foo",
field3=123,
)
data_json = json_encode(data)
instance = Input(**data, field4=data_json)
assert data_json == instance.json(exclude={"field4"})
# instance = Input(**data, field4="invalid") # this fails validation
json.dumps
function 有一个default
参数,它采用 function
对于无法以其他方式序列化的对象,会调用它。
我们可以使用它来构造我们自己的小助手 function json_encode
,它使用encode_obj_id
function 序列化ObjectIdField
类型。
由于field4
不存在于传递给该字段的验证器 function 的values
字典中,我们可以简单地在该字典上调用我们的json_encode
function 并将其与field4
值v
进行比较。
注意:这仅适用于字段 4 在field4
上最后定义的情况,因为字段按照定义的顺序进行验证。 如果您在field4
上的 field4之后有另一个字段,则在调用验证器时其值将从values
字典中丢失。
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.