Python Eve: проверка на уровне документа

Мы довольно часто использовали проверку на уровне поля, и это замечательно и мощно. Однако бывают случаи, когда сам документ действителен только при оценке более чем одного поля. Изменение любого задействованного поля должно инициировать проверку.

Что мы сделали на данный момент, так это применили проверку к каждому вовлеченному полю, что запускает проверку несколько раз при POST.

Есть ли способ применить правило проверки к самому документу?

например скажем, у some_thing есть два поля, и при проверке учитываются оба поля. Если один из них изменится, мы должны свериться с другим.

Это работает...

Валидатор (упрощено для ясности):

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...")

затем определение схемы:

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

Но мы хотели бы сделать что-то вроде этого:

Валидатор

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...")

затем определение схемы:

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

Это возможно?


person biscuit314    schedule 19.01.2018    source источник


Ответы (1)


Вы можете переопределить основной метод проверки таким образом, чтобы он сначала проверял стандартные правила, а затем правила уровня схемы:

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)

этот валидатор позволяет вам делать такие вещи, как

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

и, конечно, вам нужно реализовать validator_name так же, как указано в в документации. - в классе validator_decorator

person Maksym Rudenko    schedule 15.10.2018
comment
Когда я спросил, мы использовали Eve v0.7x. Вышесказанное работает с Eve0.8 (и, в частности, с Cerberus v1.x). Мы реализовали нечто очень похожее. - person biscuit314; 16.10.2018
comment
вчера по каким-то причинам мы понизили версию до Eve==0.7.10 и Cerberus==0.9.2 и все еще работает - person Maksym Rudenko; 16.10.2018