Тепер ми заглибимося у використання повідомлень у більш реальному сценарії — при редиректах. Якщо ти хочеш повідомити користувача про успішну (або неуспішну) дію після виконання важливого процесу (наприклад, після відправки форми або виконання якоїсь операції), тобі доведеться використовувати повідомлення з редиректами. Це не лише зробить твій код більш елегантним, але й значно допоможе покращити UX (користувацький досвід).
Що таке редирект і навіщо потрібні повідомлення при ньому?
Уяви, що користувач заповнює форму на твоєму сайті. Після її відправки ми перенаправляємо його на іншу сторінку. Але звідки йому знати, що форма була успішно збережена або що сталася помилка? Мовчання веб-застосунку викликає тривогу. Ми ж не хочемо, щоб користувач почувався самотнім у цьому світі коду.
Рішення? Повідомлення з редиректами! Вони дозволяють "пронести" сповіщення з однієї сторінки на іншу. Це можна зробити у сесії користувача: повідомлення тимчасово зберігається, поки сторінка користувача не буде оновлена або поки він не завершить поточну сесію.
Як це працює? Все просто: Django автоматично зберігає повідомлення у "мішку повідомлень" (message storage) у сесії. Після переходу на іншу сторінку і відображення повідомлення воно видаляється. Це називається тимчасовими повідомленнями.
Практика: використання повідомлень з редиректами
Почнемо з класичного сценарію: користувач відправляє форму для створення нового об'єкта. Після успішного збереження ми перенаправимо його на сторінку списку об'єктів і покажемо сповіщення.
функціональне представлення (FBV):
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import MyModelForm
from .models import MyModel
def create_object(request):
if request.method == "POST":
form = MyModelForm(request.POST)
if form.is_valid():
form.save() # Зберігаємо об'єкт
# Додаємо повідомлення про успіх
messages.success(request, "Об'єкт успішно створено!")
# Редирект користувача на сторінку зі списком об'єктів
return redirect("object_list")
else:
# Якщо форма не валідна, додаємо помилку
messages.error(request, "Помилка створення об'єкта. Перевірте дані.")
else:
form = MyModelForm()
return render(request, "create_object.html", {"form": form})
Що тут відбувається?
- Якщо форма валідна, ми створюємо об'єкт і одразу відправляємо повідомлення
successза допомогою методуmessages.success. - Потім за допомогою
redirectперенаправляємо користувача на іншу сторінку (у цьому випадку наobject_list). - Якщо форма не проходить валідацію, ми додаємо повідомлення
errorі знову рендеримо ту ж сторінку з формою.
У результаті користувач побачить сповіщення на цільовій сторінці. Зручно, правда?
Класове представлення (CBV)
Давайте перепишемо приклад на основі класових представлень. Для цього скористаємося вбудованим класом CreateView з Django.
from django.views.generic.edit import CreateView
from django.contrib import messages
from django.urls import reverse_lazy
from .models import MyModel
from .forms import MyModelForm
class MyModelCreateView(CreateView):
model = MyModel
form_class = MyModelForm
template_name = "create_object.html"
success_url = reverse_lazy("object_list")
def form_valid(self, form):
# Якщо форма валідна, зберігаємо об'єкт і додаємо повідомлення
messages.success(self.request, "Об'єкт успішно створено!")
return super().form_valid(form)
def form_invalid(self, form):
# Якщо форма не валідна, додаємо повідомлення про помилку
messages.error(self.request, "Помилка створення об'єкта. Перевірте дані.")
return super().form_invalid(form)
- У методі
form_validми додаємо повідомленняsuccessпри успішному збереженні форми. - У методі
form_invalidдодаємо повідомленняerrorпри помилці. - URL для редиректу вказується через властивість
success_url.
Додавання повідомлень у шаблонах
На одній із попередніх лекцій ми вже навчилися відображати повідомлення у шаблонах. Але щоб освіжити пам'ять, повторимо це тут.
Шаблон base.html
У типовому проєкті ти, скоріш за все, будеш відображати всі повідомлення в одному місці, наприклад, у базовому шаблоні.
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="alert {{ message.tags }}">
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
- Змінна
messagesавтоматично доступна у кожному шаблоні, якщо ти налаштувавMessageMiddleware(воно увімкнене за замовчуванням). - Властивість
message.tagsдопомагає додавати CSS-класи залежно від типу повідомлення (success,errorтощо). - Переконайся, що ти додав відповідні стилі CSS.
Стайлінг CSS
Ось приклад CSS для стилізації сповіщень. Він допоможе відокремити важливі повідомлення від менш значущих.
.alert {
padding: 10px;
margin: 5px 0;
border-radius: 4px;
font-weight: bold;
}
.alert.success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.alert.error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.alert.warning {
background-color: #fff3cd;
color: #856404;
border: 1px solid #ffeeba;
}
.alert.info {
background-color: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
Тепер твої повідомлення виглядатимуть професійно та акуратно.
Важливі моменти та типові помилки
Коли ти використовуєш редиректи з повідомленнями, важливо слідкувати за наступним:
Не забувай редиректити після додавання повідомлення. Якщо цього не зробити, повідомлення може з'явитися двічі, оскільки воно не видаляється після першого показу.
Переконайся, що
django.contrib.messagesвключений у налаштуваннях. За замовчуванням він підключений, але іноді його випадково видаляють.Старайся не зловживати повідомленнями. Якщо на одній сторінці відображається більше 3-4 повідомлень, це може заплутати користувача. Залишай лише найважливіше.
Практичне завдання
Реалізуй функціональність редиректу з повідомленнями у своєму проєкті:
- Створи представлення для створення нового об'єкта (функціональне або класове).
- Додай сповіщення про успішне створення об'єкта.
- Реалізуй повідомлення про помилку, якщо дані, введені користувачем, виявляються невалідними.
- Стилизуйте сповіщення за допомогою CSS.
Перевір, чи працює твоя система сповіщень так, як очікувалося.
Ти зробив це! Тепер твій додаток спілкується з користувачами як справжній джентльмен: воно дає зрозуміти, коли щось пішло не так, і хвалить, якщо все добре.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ