塞伯勒斯。两个键中至少应有一个是json

2024-06-26 10:52:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Cerberus来验证作为JSON发布到基于烧瓶的restapi的数据。我希望至少有两个字段freight_idtender_id中的一个。在

这些映射将被视为有效:

{"freight_id": 1, "price" : 12000}

{"tender_id": 1, "price": 12000}

{"freight_id": 1, "tender_id" : 2, "price": 12000}

但这个不会:

^{pr2}$

我如何用Cerberus为这种验证制定一个模式?在

我几乎阅读了所有的文档,但没有找到任何答案。^{}-规则不符合我的需要。在


Tags: 数据答案文档restapiidjson烧瓶规则
2条回答

@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规则,只需测试其中一个是否匹配:

^{pr2}$

使用Cerberus1.0,您可以使用oneof规则以其粘合形式实现,如本文档example。这样,您就可以针对不同的模式进行验证,其中只有一个模式必须验证:

缺点是,您可能需要对您的dict增加一个级别,如下面的price

第一种方案,运费和价格:

>>> schema_1 = {'freight_id': {'type': 'integer', 'required': True},
...             'price': {'type': 'integer', 'required': True}}

投标书和价格表:

^{pr2}$

第三种方案,运费、投标和价格:

>>> 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

相关问题 更多 >