地狱犬。至少应存在两个键之一 json
cerberus. at least one of two keys should be present is json
我正在使用 Cerberus 验证作为 JSON 发布到基于 Flask 的 ReST-API 的数据。我希望至少存在 freight_id
和 tender_id
这两个字段之一。
这些映射将被视为有效:
{"freight_id": 1, "price" : 12000}
{"tender_id": 1, "price": 12000}
{"freight_id": 1, "tender_id" : 2, "price": 12000}
虽然这个不会:
{"price": 12000}
如何使用 Cerberus 制定用于此类验证的架构?
我几乎阅读了所有文档,但没有找到任何答案。 excludes
-规则不符合我的需要。
使用 cerberus 1.0,您可以使用本文档 example 中的凝集形式的 oneof
规则来实现此目的。有了这个,您可以针对不同的模式进行验证,其中只有一个必须验证:
缺点是您的口述可能需要额外的级别,例如下面的 price
:
第一个方案、运费和价格:
>>> schema_1 = {'freight_id': {'type': 'integer', 'required': True},
... 'price': {'type': 'integer', 'required': True}}
第二个方案、招标和价格:
>>> schema_2 = {'tender_id': {'type': 'integer', 'required': True},
... 'price': {'type': 'integer', 'required': True}}
第三个方案,运费,招标及价格:
>>> schema_3 = {'tender_id': {'type': 'integer', 'required': True},
... 'freight_id': {'type': 'integer', 'required': True},
... 'price': {'type': 'integer', 'required': True}}
将这些放在一起:
>>> from cerberus import Validator
>>>
>>> price_validator = Validator(
... {'price': {'type': 'dict',
... 'oneof_schema': [schema_1, schema_2, schema_3]}})
结果:
>>> price_validator.validate({"price": {"freight_id": 1, "price" : 12000}})
True
>>> price_validator.validate({"price": {"tender_id": 2, "price" : 12000}})
True
>>> price_validator.validate(
... {"price": {"freight_id": 1, "tender_id": 2, "price": 1200}})
True
>>> price_validator.validate({"price": {"freight_id": 1, "tender_id": 2}})
False
>>> price_validator.validate({"price": {"price" : 12000}})
False
@gcw 的解决方案可以更短:
from cerberus import Validator, rules_set_registry
required_integer = {'type': 'integer', 'required': True}
schemas = (
{'freight_id': required_integer, 'price': required_integer},
{'tender_id': required_integer, 'price': required_integer},
{'freight_id': required_integer, 'tender_id': required_integer,
'price': required_integer},
)
反正这三个模式是互斥的,所以没必要使用one_of
规则,直接测试一个是否匹配:
validator = Validator()
valid = any(validator(document, schema) for schema in schemas)
我正在使用 Cerberus 验证作为 JSON 发布到基于 Flask 的 ReST-API 的数据。我希望至少存在 freight_id
和 tender_id
这两个字段之一。
这些映射将被视为有效:
{"freight_id": 1, "price" : 12000}
{"tender_id": 1, "price": 12000}
{"freight_id": 1, "tender_id" : 2, "price": 12000}
虽然这个不会:
{"price": 12000}
如何使用 Cerberus 制定用于此类验证的架构?
我几乎阅读了所有文档,但没有找到任何答案。 excludes
-规则不符合我的需要。
使用 cerberus 1.0,您可以使用本文档 example 中的凝集形式的 oneof
规则来实现此目的。有了这个,您可以针对不同的模式进行验证,其中只有一个必须验证:
缺点是您的口述可能需要额外的级别,例如下面的 price
:
第一个方案、运费和价格:
>>> schema_1 = {'freight_id': {'type': 'integer', 'required': True},
... 'price': {'type': 'integer', 'required': True}}
第二个方案、招标和价格:
>>> schema_2 = {'tender_id': {'type': 'integer', 'required': True},
... 'price': {'type': 'integer', 'required': True}}
第三个方案,运费,招标及价格:
>>> schema_3 = {'tender_id': {'type': 'integer', 'required': True},
... 'freight_id': {'type': 'integer', 'required': True},
... 'price': {'type': 'integer', 'required': True}}
将这些放在一起:
>>> from cerberus import Validator
>>>
>>> price_validator = Validator(
... {'price': {'type': 'dict',
... 'oneof_schema': [schema_1, schema_2, schema_3]}})
结果:
>>> price_validator.validate({"price": {"freight_id": 1, "price" : 12000}})
True
>>> price_validator.validate({"price": {"tender_id": 2, "price" : 12000}})
True
>>> price_validator.validate(
... {"price": {"freight_id": 1, "tender_id": 2, "price": 1200}})
True
>>> price_validator.validate({"price": {"freight_id": 1, "tender_id": 2}})
False
>>> price_validator.validate({"price": {"price" : 12000}})
False
@gcw 的解决方案可以更短:
from cerberus import Validator, rules_set_registry
required_integer = {'type': 'integer', 'required': True}
schemas = (
{'freight_id': required_integer, 'price': required_integer},
{'tender_id': required_integer, 'price': required_integer},
{'freight_id': required_integer, 'tender_id': required_integer,
'price': required_integer},
)
反正这三个模式是互斥的,所以没必要使用one_of
规则,直接测试一个是否匹配:
validator = Validator()
valid = any(validator(document, schema) for schema in schemas)