Система проверок системы
Система проверок системы — это набор статических проверок для валидации проектов 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, проверка должна выполняться для всех установленных приложений в проекте. Аргумент **kwargs требуется для дальнейшего расширения.
Сообщения
Функция должна вернуть список сообщений. Если в результате проверки проблем не обнаружено, функция проверки должна вернуть пустой список.
Предупреждения и ошибки, вызываемые методом проверки, должны быть экземплярами CheckMessage. Экземпляр CheckMessage инкапсулирует одну отслеживаемую ошибку или предупреждение. Он также предоставляет контекст и подсказки, относящиеся к сообщению, и уникальный идентификатор, используемый для фильтрации.
Концепция очень похожа на сообщения из системы сообщений или системы логирования. Сообщения помечены меткой level , указывающей на уровень серьёзности сообщения.
Существуют также сокращения для облегчения создания сообщений с общими уровнями. При использовании этих классов вы можете опустить аргумент level , так как он подразумевается именем класса.
Регистрация и маркировка проверок
Наконец, ваша функция проверки должна быть явно зарегистрирована в реестре проверок системы. Проверки должны регистрироваться в файле, который загружается при загрузке вашего приложения; например, в методе 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/2.2/topics/checks/