biscuit314
biscuit314

Reputation: 2414

Python Eve: document-level validation

We've used field-level validation quite a bit and it is wonderful and powerful. There are times, though, the document itself is valid only by assessing more than one field. Changing any field involved must trigger the validation.

What we've done for now is apply the validation to each field involved - which runs the validation multiple times on POST.

Is there a way to apply a validation rule to the document itself?

e.g. let's say some_thing has two fields and validation considers both fields. If either one changes, we must validate against the other.

This works...

The validator (simplified for clarity):

def _validate_custom_validation(self, custom_validation, field, value):
  if field == "field1":
    f1 = value
    f2 = self.document.get('field2')

  if field == "field2":
    f1 = self.document.get('field1')
    f2 = value

  if custom_validation and not is_validate(f1, f2):
    self._error(field, "validation failed...")

then the schema definition:

DOMAIN = {
  some_thing: {
    schema: {
      field1: {
        'type': 'string',
        'custom_validation': True
      },
      field1: {
        'type': 'string',
        'custom_validation': True
      }
    }
  }
}

But we would like to do something like this:

The validator

def _validate_custom_validation(self, custom_validation):
    f1 = self.document.get('field1')
    f2 = self.document.get('field2')

  if custom_validation and not is_validate(f1, f2):
    self._error(resource, "validation failed...")

then the schema definition:

DOMAIN = {
  some_thing: {
    'custom_validation': True,
    schema: {
      field1: {
        'type': 'string'
      },
      field1: {
        'type': 'string'
      }
    }
  }
}

Is this possible?

Upvotes: 0

Views: 309

Answers (1)

Maksym Rudenko
Maksym Rudenko

Reputation: 746

You can overrite main validation method in such way that it first check standart rules, and then schema level rules:

class validator_decorator(Validator):

def validate(self, document, schema=None, update=False, normalize=True):
    super(validator_decorator, self).validate(document, schema=schema, update=update, normalize=normalize)

    def validate_schema_rule(rule, document):
        validator = self.__get_rule_handler('validate', rule)
        validator(self.schema, document)

    schema_rules = app.config['DOMAIN'][self.resource].get('validation')
    if schema_rules:
        for rule in schema_rules:
            validate_schema_rule(rule, document)

    return not bool(self._errors)

this validator allows you to do things like

'users': {
    'validation': ['validator_name'],
    'schema': ...    
}

and of course you need to implement validator_name, same way as documantation says - in validator_decorator class

Upvotes: 1

Related Questions