考虑以下架构
schema = {
"value_type":{
"type": "string", "required": True
},
"units": {
"type": "string",
"dependencies": {"value_type": ["float", "integer"]},
"required": True
}
}
当units
字段的值为value_type
或float
时,我只希望 字段。
这是我要实现的行为
integer
上面的模式仅返回前3种情况的预期结果。
如果我将v = Validator(schema)
v.validate({"value_type": "float", "units": "mm"}) # 1.
True
v.validate({"value_type": "boolean", "units": "mm"}) # 2.
False
v.validate({"value_type": "float"}) # 3.
False
v.validate({"value_type": "boolean"}) # 4.
True
的定义(通过省略units
)更改为
"required": True
然后验证
"units": {"type": "string", "dependencies": {"value_type": ["float", "integer"]}}
返回v.validate({"value_type": "float"}) # 3.
True
,这不是我想要的。
我查看了documentation中的True
规则,但找不到将其仅应用于oneof
属性的方法。
我希望仅当满足依赖性时,要求的值才为required
。
我应该如何修改架构以实现此目的?
答案 0 :(得分:1)
由于您的变化跨越多个字段,*of
规则并不完全适合,尤其是因为这些规则似乎是文档中的顶级字段。
我通常会建议您仍然有Python,并且并非所有内容都必须使用模式表示,因此您可以简单地定义两个有效模式并针对这些模式进行测试:
schema1 = {...}
schema2 = {...}
if not any(validator(document, schema=x) for x in (schema1, schema2)):
boom()
与您最终得到的任何模式相比,这也更易于理解。
或者,您可以使用check_with
规则。该示例显示了两种不同的提交错误的方式,其中当错误仅呈现给人类时,后者是可取的,因为它们允许针对不同情况的自定义消息,而缺少有关错误的结构信息:
class MyValidator(Validator):
def _check_with_units_required(self, field, value):
if value in ("float", "integer"):
if "units" not in self.document:
self._error("units", errors.REQUIRED_FIELD, "check_with")
else:
if "units" in self.document:
self._error(
"units", "The 'units' field must not be provided for value "
"types other than float or integer."
)
schema = {
"value_type": {
"check_with": "units_required",
"required": True,
"type": "string"
},
"units": {
"type": "string",
}
}
validator = MyValidator(schema)
assert validator({"value_type": "float", "units": "mm"})
assert not validator({"value_type": "boolean", "units": "mm"})
assert not validator({"value_type": "float"})
assert validator({"value_type": "boolean"})