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

Есть ли способ проверить документ, в котором наличие одного поля зависит от длины другого поля? Моя попытка:

import cerberus

schema = {
    'field_2': {
        'type': 'integer',
        'dependencies': {
            'field_1': {'maxlength': 1}
        }
    },
    'field_1': {
        'type': 'list',
    }
}
v = cerberus.Validator(schema)
doc = {
    'field_1': [1, ],
    'field_2': 77
}
if not v.validate(doc):
    print(v.errors)
else:
    print(True)

выход:

{'field_2': ["depends on these values: {'field_1': {'maxlength': 1}}"]}

ожидаемый результат True


person El Ruso    schedule 14.12.2017    source источник


Ответы (2)


это можно сделать с помощью пользовательских правил:

from typing import Optional, Any, Tuple

from cerberus import Validator


class ExtendedValidator(Validator):
    def _validate_with_length(self, with_length, field, _value):
        # type: (Tuple[str, int], str, Any) -> Optional[bool]
        """Validating in dependence of length of other field in document

        The rule's arguments are validated against this schema:
        {'type': 'list'}
        """
        key, length = with_length
        if key not in self.document:
            return False
        if len(self.document[key]) != length:
            self._error(field, "Length of %s must be %s" % (key, length))


schema = {
    'field_2': {
        'type': 'integer',
        'with_length': ('field_1', 1),
    },
    'field_1': {
        'type': 'list',
    }
}

docs = [{'field_1': [1, ], 'field_2': 77}, {'field_1': [1, 2], 'field_2': 77}]
v = ExtendedValidator(schema)
for doc in docs:
    if not v.validate(doc):
        print(v.errors)
    else:
        print(True)

выход:

True
{'field_2': ['Length of field_1 must be 1']}
person El Ruso    schedule 16.12.2017

Есть смысл? Переместить 'maxlength': 1 в field_1 определение.

schema = {
    'field_2': {
        'type': 'integer',
        'dependencies': 'field_1'
    },
    'field_1': {
        'type': 'list',
        'maxlength': 1
    }
}
person Yu-Lin Chen    schedule 14.12.2017
comment
к сожалению, field_1 может быть длиннее, но только если можно использовать len(field_1) == 1 , field_2 - person El Ruso; 14.12.2017