Сообщения пользователю в Django: с чего начать новичку
Как настроить фреймворк messages в Django 5.x: подключить, вывести в шаблоне, разобраться с уровнями и не потерять сообщение после редиректа. Займёт минут двадцать.

После сохранения формы вы хотите показать «Профиль обновлён», после ошибки — «Проверьте поля». В Django для этого есть встроенная система django.contrib.messages: она держит сообщение ровно один запрос, переживает редирект и не требует хранить текст в сессии вручную. Ниже — как подключить её с нуля в Django 5.x, вывести в шаблоне и не наступить на две частые грабли: пустой блок и молчаливо пропавшее сообщение.
В конце у вас будет форма, которая после отправки перенаправляет пользователя и показывает ему зелёную плашку об успехе. Займёт минут двадцать, если проект уже создан.
Что нужно до начала
- Django 5.x и проект, который запускается командой
python manage.py runserver. - Хотя бы одно приложение с
views.pyи шаблоном, куда вы уже умеете что-то выводить. - Настроенные сессии — по умолчанию в новом проекте всё уже стоит, проверять специально не нужно.
Система сообщений в свежесозданном проекте подключена изначально. Но если вы правили settings.py руками или взяли чужой шаблон настроек, проверьте это до того, как начнёте отлаживать «почему ничего не выводится».
Шаг 1. Проверить настройки
Откройте settings.py. В списке INSTALLED_APPS должна быть строка 'django.contrib.messages', а в MIDDLEWARE — две строки:
MIDDLEWARE = [
# ...
'django.contrib.sessions.middleware.SessionMiddleware',
# ...
'django.contrib.messages.middleware.MessageMiddleware',
# ...
]Ещё в TEMPLATES внутри 'context_processors' должна быть строка 'django.contrib.messages.context_processors.messages' — именно она добавляет переменную messages в каждый шаблон. Без неё в шаблоне будет пусто, а ошибки не будет.
Как понять, что получилось: все три пункта присутствуют. Если чего-то нет — добавьте вручную и перезапустите сервер.
Шаг 2. Добавить сообщение во view
Импортируйте модуль и вызовите нужную функцию перед редиректом. Пример с функциональным view:
from django.contrib import messages
from django.shortcuts import redirect, render
def edit_profile(request):
if request.method == 'POST':
form = ProfileForm(request.POST, instance=request.user.profile)
if form.is_valid():
form.save()
# Сообщение переживёт редирект и покажется на следующей странице
messages.success(request, 'Профиль обновлён')
return redirect('profile')
else:
messages.error(request, 'Проверьте выделенные поля')
else:
form = ProfileForm(instance=request.user.profile)
return render(request, 'accounts/edit_profile.html', {'form': form})Здесь важен порядок: сообщение добавляют до redirect, а не после. Django положит его в хранилище, а на следующем запросе достанет и удалит.
Как понять, что получилось: сообщение пока никак не видно — оно появится только после Шага 3. Ошибок в консоли быть не должно.
Шаг 3. Вывести сообщения в шаблоне
Добавьте блок в тот шаблон, который видит пользователь после редиректа. Лучше — в базовый base.html, чтобы плашки работали на всех страницах:
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="{{ message.tags }}">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}Атрибут message.tags вернёт строку уровня: success, error, warning и так далее. По ней навешивайте CSS-классы для цвета. Итерация по messages — не просто чтение: она помечает сообщения как показанные, и на следующем запросе их уже не будет.
Как понять, что получилось: отправьте форму. После редиректа вверху страницы появится «Профиль обновлён». Обновите страницу ещё раз клавишей F5 — плашка исчезнет. Так и должно быть.
Уровни сообщений
У каждого сообщения есть уровень важности. Пять готовых функций закрывают почти все случаи:
| Функция | Тег (message.tags) | Когда применять |
|---|---|---|
messages.debug() | debug | Отладочная информация, в проде скрыта |
messages.info() | info | Нейтральное уведомление |
messages.success() | success | Действие завершилось успешно |
messages.warning() | warning | Предупреждение, но не ошибка |
messages.error() | error | Ошибка, действие не выполнено |
Уровень debug по умолчанию не показывается: порог отсечения задаётся настройкой MESSAGE_LEVEL. В режиме DEBUG = True порог опускается автоматически. Точные значения констант уровней смотрите в документации django.contrib.messages для вашей версии — их не нужно помнить наизусть.
Итерация по messages в шаблоне не только выводит текст — она стирает сообщения из хранилища. Показали один раз — их больше нет. Это фича, а не баг: именно поэтому плашка не висит вечно.
Если не получилось
- Блок в шаблоне есть, но пусто. Чаще всего пропущен context processor
'django.contrib.messages.context_processors.messages'вTEMPLATES. Переменнаяmessagesв шаблоне тогда просто не существует, и{% if messages %}молча даёт ложь. - Сообщение показывается, но не там, где ждали. Оно выводится на первой же странице, где отрендерится блок вывода. Если после редиректа пользователь попадает на страницу без этого блока, сообщение «съестся» на ней и до нужной не дойдёт. Держите блок в базовом шаблоне.
- MessageFailure: You cannot add messages without installing. В
MIDDLEWAREнетMessageMiddlewareили он стоит вышеSessionMiddleware. Middleware сообщений должен идти после сессий. - Сообщение живёт дольше одного запроса. Значит, где-то шаблон с блоком вывода не рендерится (например, ответ — это редирект или JSON), и сообщение не «прочиталось». Оно ждёт следующего рендера.
- Ничего не выводится в тестах или в API. Если view возвращает JSON, а не HTML, сообщения никто не читает и они копятся. Для API messages не подходят — верните текст в теле ответа.
Кастомные уровни
Если пяти встроенных уровней мало, можно добавить свой через messages.add_message() с числовой константой уровня. Это отдельная тема — для старта пяти готовых функций хватает с запасом, начинать с кастомных уровней не нужно.
Что делать дальше
Когда базовый вывод заработал, займитесь оформлением: свяжите значения message.tags с классами вашего CSS-фреймворка (в Bootstrap теги error и danger не совпадают — это правится настройкой MESSAGE_TAGS). Дальше стоит посмотреть в сторону автоскрытия плашки через несколько секунд на стороне клиента и вывода сообщений в class-based views через миксин SuccessMessageMixin. Точное имя и поведение миксина сверьте в документации Django вашей версии перед использованием.
Источники: The messages framework — Django documentation
Частые вопросы
А если у меня Django другой версии, не 5.x?
Почему сообщение исчезает после обновления страницы?
Что делать, если блок в шаблоне есть, а сообщения не выводятся?
Можно ли использовать messages в API на Django REST Framework?
Грозит ли утечкой данных то, что сообщения хранятся в сессии?
Как связать теги с классами Bootstrap?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.