Как я могу проверить поле по схеме в зависимости от значения другого поля с помощью Cerberus?

Я использую Cerberus для проверки полезной нагрузки с полем type и data. В зависимости от значения type (test или build) я хочу проверить data на соответствие различным ограничениям.

Пока у меня такая установка:

test_task = {"folder": {"required": True}}
build_task = {"environment": {"allowed": ["staging", "product"]}}
abstract_task = {'type': {'allowed': ['test', 'build']},
                 'data': {'type': 'dict',
                          'required': True,
                          'anyof': [{'schema': test_task},
                                    {'schema': build_task}]}}

Но когда предполагаемая подсхема дает сбой, также будет сообщено об ошибке, касающейся другой:

>>> validator = cerberus.Validator(schemas.abstract_task)
>>> validator.validate({
...     "type": "build",
...     "data": {"environment": "staging"}})
>>> pp validator.errors
{'data': {'anyof': 'no definitions validated',
          'definition 0': {'environment': 'unknown field',
                           'folder': 'required field'},
          'definition 1': {'environment': 'unallowed value bad'}}}

Есть ли способ условно использовать definition 1, когда родственный элемент type имеет значение build?

Этот вопрос основан на этой проблеме.


person funky-future    schedule 07.10.2017    source источник


Ответы (1)


С одной схемой и проверкой вы не можете точно достичь этого, но вы можете использовать правила oneof и dependencies, чтобы получить более четкие отчеты об ошибках:

test_task = {"folder": {"required": True}}
build_task = {"environment": {"allowed": ["staging", "product"]}}
abstract_task = {'type': {'allowed': ['test', 'build']},
                 'data': {'type': 'dict',
                          'required': True,
                          'oneof': [{'dependencies': {'type': 'test'},
                                     'schema': test_task},
                                    {'dependencies': {'type': 'build'},
                                     'schema': build_task}]}}

Вот что получается при недопустимом значении одной из подсхем:

>>> document = {"type": "build", "data": {"environment": "legacy"}}
>>> validator(document, abstract_task)
{'data': [{'oneof': ['none or more than one rule validate',
                     {'oneof definition 0': ["depends on these values: {'type': 'test'}",
                                             {'environment': ['unknown field'],
                                              'folder': ['required field']}],
                      'oneof definition 1': [{'environment': ['unallowed value legacy']}]}
                     ]}]}
person funky-future    schedule 07.10.2017