python - Cerberus - 仅当满足依赖性时才需要字段
问题描述
考虑以下架构
schema = {
"value_type":{
"type": "string", "required": True
},
"units": {
"type": "string",
"dependencies": {"value_type": ["float", "integer"]},
"required": True
}
}
我希望仅当字段的值为or时才units
需要该字段。value_type
float
integer
这是我想要实现的行为
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
上述 Schema 仅返回前 3 种情况的预期结果。
如果我将units
(通过省略"required": True
)的定义更改为
"units": {"type": "string", "dependencies": {"value_type": ["float", "integer"]}}
然后验证
v.validate({"value_type": "float"}) # 3.
True
返回True
这不是我想要的。
我查看了文档oneof
中的规则,但找不到仅将其应用于属性的方法。required
我希望 required 的值True
仅在满足依赖项时才存在。
我应该如何修改我的架构来实现这一点?
解决方案
由于您的变体跨越多个字段,因此*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"})
推荐阅读
- python - Flask 在 WSGI 服务器中抛出 ascii 字符错误,但在调试本地服务器中没有?
- c++ - 如何在单个 Visual Studio Code 解决方案中编译多个独立的 C++ 程序
- flow-project - 运行 python 示例/simulate.py 时开始使用时出现错误
- reporting-services - 自定义添加的状态原因不会通过 FilteredView 显示在 SSRS 报告中
- ios - 在 iOS Swift 中使用 SvgKit 更改 SVG 颜色
- python - Django GraphQL 端点测试无法使用“变量”字典
- twilio - Twilio iOS sdk - 一对一视频通话
- jquery - 打开后如何使用 jQuery 关闭/隐藏此 div?
- networking - 如何使 TCP 套接字连接在具有不同 ISP 的 WAN 上工作?
- android - ReactApplicationContext 无法转换为 AppCompatActivity