Spec-Zone.ru › Django 1.8

Система проверки фреймворка

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

Проверки можно явно запустить с помощью команды check. Проверки запускаются неявно перед большинством команд, включая runserver и migrate. По соображениям производительности, проверки не выполняются в рамках стека WSGI, используемого при развертывании. Если вам нужно запустить проверки системы на сервере развертывания, запустите их явно с помощью check.

Серьёзные ошибки помешают выполнению команд Django (таких как runserver) вообще. Незначительные проблемы выводятся в консоль. Если вы изучили причину предупреждения и хотите его проигнорировать, вы можете скрыть определённые предупреждения, используя настройку SILENCED_SYSTEM_CHECKS в файле настроек вашего проекта.

Полный список всех проверок, которые могут быть подняты Django, можно найти в Справочнике по проверкам системы.

Написание собственных проверок

Фреймворк гибкий и позволяет вам писать функции, выполняющие любой другой вид проверки, которая может потребоваться. Ниже приведён пример функции-заглушки для проверки:

from django.core.checks import Error, register

@register()
def example_check(app_configs, **kwargs):
    errors = []
    # ... your check logic here
    if check_failed:
        errors.append(
            Error(
                'an error',
                hint=None,
                obj=checked_object,
                id='myapp.E001',
            )
        )
    return errors

Функция проверки должна принимать аргумент app_configs; этот аргумент — список приложений, которые должны быть проверены. Если None, проверка должна выполняться для всех установленных приложений в проекте. Аргумент **kwargs требуется для будущих расширений.

Сообщения

Функция должна вернуть список сообщений. Если в результате проверки проблем не обнаружено, функция проверки должна вернуть пустой список.

Предупреждения и ошибки, вызываемые методом проверки, должны быть экземплярами CheckMessage. Экземпляр CheckMessage описывает одну отслеживаемую ошибку или предупреждение. Он также предоставляет контекст и подсказки, применимые к сообщению, а также уникальный идентификатор, используемый для фильтрации.

Концепция очень похожа на сообщения из фреймворка сообщений или фреймворка регистрации. Сообщения помечены тегом level, указывающим на уровень важности сообщения.

Также существуют сокращения, упрощающие создание сообщений с общими уровнями. При использовании этих классов вы можете опустить аргумент level, так как он подразумевается именем класса.

  • Debug
  • Info
  • Warning
  • Error
  • Critical

Регистрация и маркировка проверок

Наконец, ваша функция проверки должна быть явно зарегистрирована в реестре проверок системы. Проверки должны быть зарегистрированы в файле, который загружается при загрузке вашего приложения; например, в методе AppConfig.ready().

register(*tags)(function)

Вы можете передать любое количество тегов в register для маркировки вашей проверки. Маркировка проверок полезна, поскольку позволяет запускать только определённую группу проверок. Например, для регистрации проверки совместимости вы бы сделали следующий вызов:

from django.core.checks import register, Tags

@register(Tags.compatibility)
def my_check(app_configs, **kwargs):
    # ... perform compatibility checks and collect errors
    return errors

Вы можете зарегистрировать «проверки развертывания», которые актуальны только для файла настроек производства, как это:

@register(Tags.security, deploy=True)
def my_check(app_configs, **kwargs):
    ...

Эти проверки будут выполняться только в том случае, если опция --deploy передаётся команде check.

Вы также можете использовать register в качестве функции вместо декоратора, передав вызываемый объект (обычно функцию) в качестве первого аргумента register.

Следующий код эквивалентен вышеприведённому коду:

def my_check(app_configs, **kwargs):
    ...
register(my_check, Tags.security, deploy=True)

Добавлена возможность использования register в качестве функции.

Проверки полей, моделей и менеджеров

В некоторых случаях вам не нужно будет регистрировать вашу функцию проверки — вы можете использовать уже существующую регистрацию.

Поля, модели и менеджеры моделей реализуют метод check(), который уже зарегистрирован в фреймворке проверок. Если вы хотите добавить дополнительные проверки, вы можете расширить реализацию базового класса, выполнить любые дополнительные проверки, которые вам нужны, и добавить любые сообщения к тем, которые генерируются базовым классом. Рекомендуется делегировать каждую проверку отдельным методам.

Рассмотрим пример, где вы реализуете пользовательское поле с именем RangedIntegerField. Это поле добавляет аргументы min и max к конструктору IntegerField. Возможно, вы захотите добавить проверку, чтобы убедиться, что пользователи предоставляют минимальное значение, которое меньше или равно максимальному значению. Следующий фрагмент кода демонстрирует, как реализовать эту проверку:

from django.core import checks
from django.db import models

class RangedIntegerField(models.IntegerField):
    def __init__(self, min=None, max=None, **kwargs):
        super(RangedIntegerField, self).__init__(**kwargs)
        self.min = min
        self.max = max

    def check(self, **kwargs):
        # Call the superclass
        errors = super(RangedIntegerField, self).check(**kwargs)

        # Do some custom checks and add messages to `errors`:
        errors.extend(self._check_min_max_values(**kwargs))

        # Return all errors and warnings
        return errors

    def _check_min_max_values(self, **kwargs):
        if (self.min is not None and
                self.max is not None and
                self.min > self.max):
            return [
                checks.Error(
                    'min greater than max.',
                    hint='Decrease min or increase max.',
                    obj=self,
                    id='myapp.E001',
                )
            ]
        # When no error, return an empty list
        return []

Если вы хотели добавить проверки к менеджеру модели, вы бы использовали тот же подход в своём подклассе Manager.

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

class MyModel(models.Model):
    @classmethod
    def check(cls, **kwargs):
        errors = super(MyModel, cls).check(**kwargs)
        # ... your own checks ...
        return errors

Написание тестов

Сообщения сопоставимы. Это позволяет легко писать тесты:

from django.core.checks import Error
errors = checked_object.check()
expected_errors = [
    Error(
        'an error',
        hint=None,
        obj=checked_object,
        id='myapp.E001',
    )
]
self.assertEqual(errors, expected_errors)

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.8/topics/checks/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API