Перейти к содержанию

Пользовательская валидация

InfraVision валидирует каждый объект перед его записью в базу данных для обеспечения целостности данных. Эта валидация включает такие вещи, как проверка правильного форматирования и того, что ссылки на связанные объекты действительны. Однако вы можете захотеть дополнить эту валидацию некоторыми собственными правилами. Например, возможно, вам требуется, чтобы имя каждой площадки соответствовало определённому шаблону. Это можно сделать с помощью пользовательских правил валидации.

Пользовательские правила валидации

Пользовательские правила валидации выражаются как сопоставление атрибутов объекта с набором правил, которым этот атрибут должен соответствовать. Например:

{
  "name": {
    "min_length": 5,
    "max_length": 30
  }
}

Это определяет пользовательский валидатор, который проверяет, что длина атрибута name для объекта составляет не менее пяти символов и не более 30 символов. Эта валидация выполняется после того, как InfraVision выполнит свою собственную внутреннюю валидацию.

Типы валидации

Класс CustomValidator поддерживает несколько типов валидации:

  • min: Минимальное значение
  • max: Максимальное значение
  • min_length: Минимальная длина строки
  • max_length: Максимальная длина строки
  • regex: Применение регулярного выражения
  • required: Значение должно быть указано
  • prohibited: Значение не должно быть указано
  • eq: Значение должно быть равно указанному значению
  • neq: Значение не должно быть равно указанному значению

Типы min и max должны быть определены для числовых значений, тогда как min_length, max_length и regex подходят для символьных строк (текстовых значений). Валидаторы required и prohibited могут использоваться для любого поля, и им должно быть передано значение True.

Внимание

Имейте в виду, что эти валидаторы лишь дополняют собственную валидацию InfraVision: они не переопределяют её. Например, если определённое поле модели обязательно для InfraVision, установка для него валидатора с {'prohibited': True} не сработает.

Пользовательская логика валидации

Могут быть случаи, когда предоставленных типов валидации недостаточно. InfraVision предоставляет класс CustomValidator, который можно расширить для применения произвольной логики валидации путём переопределения его метода validate() и вызова fail() при обнаружении неудовлетворительного условия. Метод validate() должен принимать экземпляр (сохраняемый объект), а также текущий запрос, осуществляющий изменение.

from extras.validators import CustomValidator

class MyValidator(CustomValidator):

    def validate(self, instance, request):
        if instance.status == 'active' and not instance.description:
            self.fail("Активные площадки должны иметь заданное описание!", field='status')

Метод fail() может опционально указывать поле, с которым следует связать предоставленное сообщение об ошибке. Если указано, сообщение об ошибке будет отображаться пользователю как связанное с этим полем. Если опущено, сообщение об ошибке не будет связано ни с каким полем.

Назначение пользовательских валидаторов

Пользовательские валидаторы связываются с конкретными моделями InfraVision через параметр конфигурации CUSTOM_VALIDATORS. Существует три способа определения пользовательских правил валидации:

  1. Простое JSON-сопоставление (без пользовательской логики)
  2. Путь с точками к классу пользовательского валидатора
  3. Прямая ссылка на класс пользовательского валидатора

Простые данные

Для случаев, когда пользовательская логика не нужна, достаточно передать правила валидации как простые JSON-совместимые объекты. Этот подход обычно обеспечивает наибольшую переносимость вашей конфигурации. Например:

CUSTOM_VALIDATORS = {
    "dcim.site": [
        {
            "name": {
                "min_length": 5,
                "max_length": 30,
            }
        }
    ],
    "dcim.device": [
        {
            "platform": {
                "required": True,
            }
        }
    ]
}

Ссылки на атрибуты связанных объектов

На атрибуты связанного объекта можно ссылаться, указав путь с точками. Например, чтобы сослаться на имя региона, к которому назначена площадка, используйте region.name:

CUSTOM_VALIDATORS = {
    "dcim.site": [
        {
            "region.name": {
                "neq": "New York"
            }
        }
    ]
}

Валидация параметров запроса

В дополнение к валидации атрибутов объекта пользовательские валидаторы также могут сопоставляться с параметрами текущего запроса (где это доступно). Например, следующее правило разрешит только пользователю с именем "admin" изменять объект:

{
  "request.user.username": {
    "eq": "admin"
  }
}

Совет

Пользовательская валидация, как правило, не должна использоваться для применения разрешений. InfraVision предоставляет надёжный механизм разрешений на основе объектов, который должен использоваться для этой цели.

Путь с точками к классу

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

CUSTOM_VALIDATORS = {
    'dcim.site': (
        'my_validators.Validator1',
        'my_validators.Validator2',
    ),
    'dcim.device': (
        'my_validators.Validator3',
    )
}

Прямая ссылка на класс

Этот подход требует, чтобы каждый создаваемый экземпляр класса был импортирован непосредственно в файле конфигурации Python.

from my_validators import Validator1, Validator2, Validator3

CUSTOM_VALIDATORS = {
    'dcim.site': (
        Validator1(),
        Validator2(),
    ),
    'dcim.device': (
        Validator3(),
    )
}

Примечание

Даже если определяется только один валидатор, он должен быть передан как итерируемый объект.