Spec-Zone.ru › Django 4.1

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

Система проверки фреймворка — это набор статических проверок для валидации проектов 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='A hint.',
                obj=checked_object,
                id='myapp.E001',
            )
        )
    return errors

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

Проверка получит ключевой аргумент databases. Это список псевдонимов баз данных, подключения к которым могут быть использованы для проверки конфигурации уровня базы данных. Если databases равно 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):
    ...

Эти проверки будут выполняться только если используется опция check --deploy.

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

Код ниже эквивалентен коду выше:

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

Проверки полей, моделей, менеджеров и баз данных

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

Поля, модели, менеджеры моделей и бэкэнды баз данных реализуют метод 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().__init__(**kwargs)
        self.min = min
        self.max = max

    def check(self, **kwargs):
        # Call the superclass
        errors = super().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().check(**kwargs)
        # ... your own checks ...
        return errors

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

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

from django.core.checks import Error
errors = checked_object.check()
expected_errors = [
    Error(
        'an error',
        hint='A hint.',
        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/4.1/topics/checks/

Spec-Zone.ru

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