Cerberus自定义类型验证问题:如何实现带~前缀的fudge类型?
修复Cerberus自定义类型验证的问题
我来帮你搞定这个自定义fudge类型的验证问题!你的代码里有几个关键错误导致验证没有按预期工作,咱们一步步拆解:
核心问题:自定义类型验证方法的签名错误
Cerberus中,自定义类型的验证方法命名规则是_validate_type_{typename},但它的方法签名只接收value作为参数,而不是你写的field, value。正因为签名不对,Cerberus根本没调用你的_validate_type_fudge方法,所以验证直接返回了True,完全没触发你的错误逻辑。
其他需要修正的问题
additional_context的@property实现有问题:每次访问都会调用self._error,这会在不该报错的时候添加错误,而且逻辑上应该是从配置中获取值,而不是强制报错。- 你没有在验证时传入
additional_context的配置,即便方法正确,也无法使用这个上下文。
修正后的完整代码
import cerberus # 定义自定义类型 fudge_type = cerberus.TypeDefinition('fudge_type', (str,), ()) class MyValidator(cerberus.Validator): # 复制默认类型映射并添加自定义类型 types_mapping = cerberus.Validator.types_mapping.copy() types_mapping['fudge'] = fudge_type def __init__(self, *args, **kwargs): # 从kwargs中提取additional_context并存入实例 self.additional_context = kwargs.pop('additional_context', 'bar') super().__init__(*args, **kwargs) # 正确实现自定义类型的验证方法 def _validate_type_fudge(self, value): # 检查值是否以~开头 if not isinstance(value, str) or not value.startswith('~'): self._error('name', "值必须是前缀为~的字符串!") # 正常使用additional_context print(f"使用上下文参数: {self.additional_context}") # 初始化验证器并传入自定义上下文 validator = MyValidator(additional_context='my_custom_context') # 测试不符合要求的值 result = validator.validate({'name': 'yada'}, {'name': {'type': 'fudge'}}) print(f"验证结果: {result}") print(f"错误信息: {validator.errors}") # 测试符合要求的值 result2 = validator.validate({'name': '~yada'}, {'name': {'type': 'fudge'}}) print(f"验证结果: {result2}")
关键改动说明
- 修正验证方法签名:把
_validate_type_fudge的参数从field, value改为value,这样Cerberus会正确识别并调用这个方法。 - 实现正确的验证逻辑:在方法里检查值是否为字符串且以
~开头,不符合则添加错误提示。 - 修复上下文属性:在
__init__中提取additional_context并保存为实例属性,避免每次访问都触发错误,同时可以正常在验证方法中调用。 - 传入上下文配置:初始化
MyValidator时传入additional_context参数,确保上下文能被正确获取和使用。
现在运行代码,当值不以~开头时,验证会返回False并给出错误信息,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Pithikos
相关产品推荐
相关产品推荐

