如果您只想让url
字段接受None
作为特例,但是保存一个空字符串,那么您仍然应该将其声明为常规的str
类型字段.您可以在定制的pre=True
validator中处理特殊情况.那里不需要自定义数据类型.
from pydantic import BaseModel, validator
class Model(BaseModel):
url: str
@validator("url", pre=True)
def none_to_empty(cls, v: object) -> object:
if v is None:
return ""
return v
model = Model(url=None)
print(model.json()) # {"url": ""}
更新
如果不想在不同的模型中为不同的字段重复验证器,可以在自定义base model上定义一个通用的pre=True
验证器,并实现某种逻辑来识别模型上的哪些字段要处理以及如何处理.
一种 Select 是利用typing.Annotated
将任何给定的类型与一些应该调用的自定义转换函数"打包".然后,通用验证器将判断Annotated
元数据的每个字段,如果找到一个函数,它将对该值调用该函数.
以下是一个有效的示例:
from typing import Annotated, get_origin
from pydantic import BaseModel as PydanticBaseModel, validator
from pydantic.fields import ModelField
class BaseModel(PydanticBaseModel):
@validator("*", pre=True)
def process_annotated(cls, v: object, field: ModelField) -> object:
if get_origin(field.annotation) is not Annotated:
return v
func = field.annotation.__metadata__[0]
if not callable(func):
return v
return func(v)
StrOrNone = Annotated[str, lambda v: "" if v is None else v]
class Model1(BaseModel):
url: StrOrNone
print(Model1(url=None).json()) # {"url": ""}