Программы
Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

Добавляем переменные в контекст Django шаблонов (свой контекст-процессор)

В Django вы можете передавать данные в шаблоны посредством контекстов. Контекст передаётся из контроллера (view в терминах Django), однако, если одни и те же данные нужны в разных местах, лучше сделать свой контекст-процессор.

В проектах на Django часто взаимодействие с пользователем осуществляется через отрендеренные html-шаблоны. Да, есть вариант поставить один из модулей rest-*, которые обеспечат интерфейс взаимодействия через json... Но в основной массе используется всё же HTML интерфейс.

И чтобы отрендерить шаблон, нам нужно непосредственно описать сам шаблон, а также передать в него информацию, которая будет вставлена в указанные места. Передать контекст. И помимо того, что можно передать непосредственно из view (контроллера), в контексте шаблона присутствуют и другие переменные, например messages, user. Если приглядеться в settings.py, то можно увидеть, как они добавляются в наши шаблоны:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [f'{BASE_DIR}/templates'],
        'APP_DIRS': True,
        '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',  # <---
            ],
        },
    },
]

То есть, если мы, например, хотим на всех страницах выводить плашку с последними опубликованными заметками, нам нужно либо во всех view их получать, либо же написать свой контекстный процессор. Именно это мы сейчас и сделаем.

Для начала создадим модуль, в котором будем писать его (в Django приложении post):

post
├───context_processors
     ├──post_context.py
     ├──__init__.py

Сам же контекстный процессор имеет крайне простой интерфейс - это функция, которой на вход передаётся request, а возвращается словарь с переменными контекста, которые надо добавить.

Напишем свой контекстный процессор в модуле post.context_processors.post_context:

from post.models import Post


def last_posts(request):
    posts = Post.objects.order_by('-published')[:10]
    return {
        'last_posts': posts
    }

После чего добавим его в список контекст-процессоров в файле настроек settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [f'{BASE_DIR}/templates'],
        'APP_DIRS': True,
        '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',
                'post.context_processors.post_context.last_posts',  # Добавили эту строку
            ],
        },
    },
]

После чего можно в любом шаблоне уже использовать эту переменную:

...
{% for post in last_posts %}
    {{post}}
{% endfor %}
...

Теперь вы можете в Django проекте добавить любую переменную шаблона на свой вкус!

Если интересно, что дальше - читайте рубрику Django.

Изображение Python 3.11. Что нового?