云计算百科
云计算领域专业知识百科平台

Pydantic动态生成BaseModel作数据验证并自定义校验规则

场景

常规的数据验证的方式这里就不在赘述了,网上有很多资料。
在实际业务中,有时候出出现这种情况,比如数据库表中有N多个字段,且有M张表,每个输入字段都对应表中的一个字段,并且前后端需要严格校验, 如果我们手写这样的basemodel既费时费力,而且写出的代码臃肿且不易扩展。
所以需要能动态生成basemodel,这样如果表中或者配置中字段有增减就不需要手动修改basemodel类了。
强大的Pydantic提供了这么一种机制。

假设有这种一种场景,从配置或者表中获取待验证的字段,验证从前端输入的值都否在某个范围,且支持分页查询。 某公司员工年龄规定在20~65岁之间,正常薪资范围5000-50000/月
age(20~65)
salary(5000~50000)

配置如下:

config = {
“age”: {“min”: 20, “max”: 65},
“salary”: {“min”: 5000, “max”: “50000”}
}

伪代码实现

from pydantic import create_model, field_validator, BaseModel

# 分页基本模型
class BasePreciseFilterModel(BaseModel):
page: int = 1
page_size: int = 10

# 校验函数
def check_min_max_value(key)

baseline_min_value = config[key]["min"]
baseline_max_value = coofig[key]["max"]

# 这边其实用了一个闭包,用于传入配置中的key,并和这里 v 中传入的前端输入参数中的只做校验
def _check_min_max_value(cls, v):
_min_value_input = v.get("min")
_max_value_input = v.get("max")

if _min_value_input < baseline_min_value:
raise ValueError(...)
if _max_value_input > baseline_max_value:
raise ValueError(...)

return v
return _check_min_max_value

# 生成每个属性的校验器, 这里的 field_validator 实际是一个类装饰器
validators = {
f"{key}_validator": field_validator(key)(check_min_max_value(key))
for key in config.keys()
}

# 动态生成的最终Model类
PreciseSearchFilterModel = create_model(
"PreciseSearchFilterModel ",
**{key: (dict | None, None) for key in config.keys()},
__validators__=validators,
__base__=BasePreciseFilterModel
)

# 接下来就可以应用这个Model类验证输入了, 比如在我们的 Django、Flask、FastApi等项目中。
# 前端传入的payload如下, 搜索年龄在 25~60岁之间,且薪资在10000~20000区间的员工
{"age": {"min": 25, "max": 60}, "salary": {"min": 10000, "max": 20000}, "page":1, "page_size": 5}

@app.route("filter")
def precise_filter(filter: PreciseSearchFilterModel):

filter_params = filter.model_dump()
page = filter_params.pop("page")
page_size = filter_params.pop("page_size")

# TODO 业务逻辑

赞(0)
未经允许不得转载:网硕互联帮助中心 » Pydantic动态生成BaseModel作数据验证并自定义校验规则
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!