Машинный перевод под контролем человека
Этот контент переведён с помощью машинной генерации, направляемой составленными людьми глоссариями и руководствами по стилю. Поскольку текст не проверяется вручную построчно, возможны отдельные ошибки или неестественные формулировки.
В случае любых расхождений авторитетным источником считается оригинальная версия на английском языке.
Flash-сообщения
Flash-сообщения дают пользователю временную одноразовую обратную связь после выполнения действия, например «Запись успешно создана» или «Недопустимый тип файла». Сообщение переживает один HTTP-редирект, после отображения административная панель его удаляет.
Функция flash() ставит сообщение в очередь текущего запроса. Административная панель отобразит это сообщение на следующей странице, которую увидит пользователь, а затем очистит очередь. Этот паттерн пришёл из Flask-Admin.
from starlette.requests import Request
from starlette_admin import BaseModelView
from starlette_admin.flash import flash
class PostView(BaseModelView):
async def before_create(self, request: Request, data: dict) -> None:
if not data.get("title", "").strip():
# Ставим сообщение в очередь для следующей загрузки страницы
flash(request, "Title cannot be blank.", category="error")
raise ValueError("Title cannot be blank.")
Категории сообщений
Каждое flash-сообщение требует указания категории. Категория определяет цвет баннера в стандартной теме оформления, что позволяет пользователю мгновенно оценить серьёзность ситуации.
from starlette_admin.flash import flash
flash(request, "Report generated.", category="success")
flash(request, "3 rows were skipped.", category="info")
flash(request, "This action can't be undone.", category="warning")
flash(request, "Upload failed: file too large.", category="error")
Аргумент category по умолчанию имеет значение "info". Он должен быть строго одним из следующих: success, info, warning или error. Любое другое значение приведёт к исключению ValueError.
Встроенные CRUD-сообщения
Для стандартных CRUD-операций вызывать flash() вручную не требуется. Административная панель автоматически показывает сообщение с категорией success после завершения следующих действий:
| Действие | Сообщение по умолчанию |
|---|---|
| Создание | The item "<repr>" was added successfully. |
| Редактирование | The item "<repr>" was changed successfully. |
| Удаление (одиночное) | The item "<repr>" was successfully deleted. |
| Удаление (массовое) | %(count)d items were successfully deleted. |
Что подставляется вместо <repr>
Автоматические сообщения используют представление строки, которое определяет метод view.repr(), а не имя класса модели. Например, при создании записи будет показано сообщение "The item 'My First Post' was added successfully", а не общее "Post was added successfully".
Использование flash-сообщений в кастомных действиях
Обработчики кастомных действий (@action и @row_action) по умолчанию возвращают None. Чтобы дать пользователю обратную связь, вызовите flash() до того, как обработчик завершит работу.
from starlette.requests import Request
from starlette_admin import BaseModelView, action, flash
class PostView(BaseModelView):
@action(
name="publish",
text="Publish",
confirmation="Publish the selected posts?",
)
async def publish_action(self, request: Request, pks: list) -> None:
for pk in pks:
obj = await self.find_by_pk(request, pk)
obj.published = True
await self.edit(request, pk, {"published": True})
# Уведомляем пользователя об успешном выполнении кастомного действия
flash(request, f"{len(pks)} post(s) published.", category="success")
- Если вы не вызываете
flash(): действие всё равно выполнится, но после редиректа страницы пользователь не получит визуального подтверждения. - Если действие завершилось ошибкой: когда ваш кастомный обработчик выбрасывает исключение
ActionFailed, административная панель перехватывает его и отображает текст исключения в виде баннера с ошибкой. Не вызывайтеflash()в веткеActionFailed, поскольку запрос в этом случае не выполняет редирект.
Отображение сообщений в кастомных шаблонах
Базовый шаблон административной панели извлекает и отображает flash-сообщения автоматически. Извлекать их самостоятельно нужно только при создании полностью кастомного представления.
from starlette_admin.flash import get_flashed_messages
messages = get_flashed_messages(request)
# Returns: [{"message": "The item \"My First Post\" was added successfully.", "category": "success"}]
Чтение очереди flash-сообщений — операция разрушающая. Первый вызов get_flashed_messages(request) извлекает и очищает очередь. Последующие вызовы в рамках того же запроса вернут пустой список [].
Держите сообщения короткими
Flash-сообщения хранятся в подписанной cookie с флагом httponly под именем admin_flash, а не в серверной сессии. Браузеры ограничивают размер cookie примерно 4 КБ, поэтому используйте flash-сообщения только для краткой обратной связи. Избегайте длинных строк и больших объёмов данных. Кроме того, подход на основе cookie означает, что flash-сообщения работают без SessionMiddleware.
Пример работающего приложения, вызывающего
flash()из hook'ов и кастомных действий, см. в examples/09-actions.
Что дальше
- Действия: запускайте бизнес-логику из массовых или строчных действий.
- Безопасность: узнайте, как параметр
secret_keyзащищает и flash-cookie, и CSRF-токены. - Шаблоны: отображайте flash-баннеры внутри собственных макетов.