Что такое контекстный процессор (context processor) в Django?

Ответ

Контекстный процессор (context processor) в Django — это функция, которая добавляет дополнительные данные в контекст всех шаблонов, обрабатываемых Django. Это позволяет избежать дублирования кода при передаче одних и тех же переменных в каждый шаблон вручную.

Зачем использовать? Контекстные процессоры идеально подходят для глобальных данных, которые должны быть доступны в любом шаблоне вашего проекта, например:

  • Настройки сайта (название, URL)
  • Информация о текущем пользователе (если не используется auth контекстный процессор по умолчанию)
  • Содержимое корзины покупок
  • Глобальные навигационные элементы

Пример создания и регистрации:

  1. Создайте файл context_processors.py в вашем приложении (например, myapp/context_processors.py):

    # myapp/context_processors.py
    def site_info(request):
        """Добавляет глобальную информацию о сайте в контекст шаблонов."""
        return {
            'SITE_NAME': 'Мой Замечательный Сайт',
            'SITE_URL': 'https://example.com',
            'CURRENT_YEAR': 2023 # Пример динамического значения
        }
  2. Зарегистрируйте процессор в settings.py в секции TEMPLATES:

    # settings.py
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                    # Ваш кастомный контекстный процессор
                    'myapp.context_processors.site_info',
                ],
            },
        },
    ]

Использование в шаблоне: После регистрации, переменные SITE_NAME, SITE_URL и CURRENT_YEAR будут доступны в любом шаблоне:

<!-- base.html или любой другой шаблон -->
<footer>
    <p>&copy; {{ CURRENT_YEAR }} {{ SITE_NAME }}. Все права защищены.</p>
    <p>Посетите нас: <a href="{{ SITE_URL }}">{{ SITE_URL }}</a></p>
</footer>

Важное замечание: Контекстные процессоры выполняются для каждого запроса. Избегайте добавления в них тяжеловесной логики или запросов к базе данных, которые могут замедлить работу вашего приложения.

Ответ 18+ 🔞

Да ты посмотри, что за хуйня творится в Django с этими шаблонами! Ну реально, как обезьяна с гранатой: в каждом контроллере одно и то же писать, чтобы в шаблон передать. Сайт называется, год текущий, юзверя проверить... Задолбало, ёпта!

А тут, оказывается, умные люди придумали контекстный процессор — это такая хитрая жопа, которая сама, блядь, в каждый шаблон нужные переменные подкладывает. Один раз настроил — и похуй, в каком месте рендеришь, всё уже там есть.

Нахуя это надо, спросишь? А нахуя, блядь, по сто раз писать одно и то же? Вот представь: тебе в каждом шаблоне футера нужен год и название сайта. И что, в каждый render это пихать? Да ты с ума сошёл! Вот для этого глобального говна контекстный процессор и создан. Корзина покупок, настройки, какая-нибудь хуйня для меню — всё туда.

Как эту магию, блядь, сделать:

  1. Создаёшь файлик context_processors.py прямо в своём приложении. Туда пишешь функцию, которая из request (или просто из воздуха) данные достаёт и словарь возвращает.

    # myapp/context_processors.py
    def site_info(request):
        """Подкидывает в каждый шаблон инфу о сайте, чтоб не писать вручную."""
        return {
            'SITE_NAME': 'Мой Охуенный Сайт',
            'SITE_URL': 'https://moysayt.ru',
            'CURRENT_YEAR': 2023
        }
  2. Прописываешь эту функцию в настройках, в settings.py, в секции TEMPLATES. Там уже куча стандартных сидит, твою просто в конец списка суёшь.

    # settings.py
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                    # А вот и наш самопальный красавец
                    'myapp.context_processors.site_info',
                ],
            },
        },
    ]

И всё, пиздец! Теперь в любом шаблоне, хоть в base.html, хоть в самом замудрённом, эти переменные доступны, как родные.

<!-- base.html -->
<footer>
    <p>&copy; {{ CURRENT_YEAR }} {{ SITE_NAME }}. Все права в жопе.</p>
    <p>Заходи ещё: <a href="{{ SITE_URL }}">{{ SITE_URL }}</a></p>
</footer>

Но предупреждаю, как старший товарищ: эта штука вызывается на КАЖДЫЙ запрос, ёбта! Не вздумай туда тяжёлые запросы к базе или пятиэтажную логику пихать, а то сайт твой накроется медным тазом от нагрузки. Используй с умом, для лёгкой, но везде нужной хуйни.