Tengo un gran documento json, donde algunos campos deberían ser obligatorios si otros campos tienen valores exactos. P.ej
document = {'is_realty_address': False, 'postcode': 111111}
el código postal tiene que ser requerido si is_realty_address == False. Todas las reglas (excepto 'obligatorias') se aplican a los campos que existen en el documento, por lo que mis reglas personalizadas son silenciosas, cuando tengo
document = {'is_realty_address': False}
of-rules no ayudará en mi caso, porque tengo muchos campos "requeridos condicionalmente" que dependen de muchos campos diferentes. Entonces, las reglas of complicarán mucho mi esquema. Las dependencias tampoco funcionan. Lo intenté:
{'postcode': {'dependencies': {'is_realty_address': False}, 'required': True}}
Esto devuelve un error si el código postal no aparece en el documento, sin importar el valor que tenga is_realty_address
v = Validator() print(v.validate({'is_realty_address': False}, schema)) print(v.errors) print(v.validate({'is_realty_address': True}, schema)) print(v.errors)
este código devuelve:
False {'postcode': ['required field']} False {'postcode': ['required field']}
También traté de implementar el método de validación:
def _validate_conditional_required(self, conditional_required, field, value): """ :param conditional_required: :param field: :param value: :return: The rule's arguments are validated against this schema: {'type': 'dict'} """ for conditional_field, conditional_value in conditional_required.items(): if self.document[conditional_field] == conditional_value and field not in self.document: self._error(field, errors.REQUIRED_FIELD)
con esquema
schema = { 'is_realty_address': {'required': True, 'type': 'boolean'}, 'postcode': {'conditional_required': {'is_realty_address': False}}, }
pero esta regla no se ejecuta si el 'código postal' no está en el documento.
¿Hay alguna forma de establecer la regla "requerido condicional"? Quiero ver este código:
schema = { 'is_realty_address': {'required': True, 'type': 'boolean'}, 'postcode': {'conditional_required': {'is_realty_address': False}}, } v = Validator() print(v.validate({'is_realty_address': False}, schema)) print(v.errors) print(v.validate({'is_realty_address': True}, schema)) print(v.errors)
devoluciones:
True False {'postcode': ['required field']}
Descubrí que mi problema se puede resolver con la combinación de la regla 'excluye' y 'uno de'
schema = { 'is_realty_address': { 'required': True, 'type': 'boolean', 'oneof': [{'excludes': 'postcode', 'allowed': [False]}, {'allowed': [True]}] }, 'postcode': {'type': 'integer', 'required': True}} v = Validator() print(v.validate({'is_realty_address': True}, schema)) print(v.errors) print(v.validate({'is_realty_address': False, 'postcode': 111111}, schema)) print(v.errors)
Este código devuelve:
False {'postcode': ['required field']} False {'is_realty_address': [{'oneof': ['none or more than one rule validate', {'oneof definition 1': ['unallowed value False'], 'oneof definition 0': ["'postcode' must not be present with 'is_realty_address'"]}]}]}
Por lo tanto, el esquema no será muy complicado con esta variante.