Модальные компоненты
AdminModal предоставляет переиспользуемое диалоговое окно с проверкой прав
на любой странице Chassis Admin. Общая оболочка рендерится один раз, а fragment
конкретного modal загружается только после вызова trigger.
Объявление и регистрация modal
from django.http import HttpRequest, HttpResponse
from django_chassis.components import PermissionAdminModal
from django_chassis.options import PermissionOption
class ReconcileModal(PermissionAdminModal):
slug = 'reconcile'
title = 'Reconcile records'
template_name = 'admin/project/reconcile_modal.html'
permission = PermissionOption(
app_label='operations',
model='reconciliation',
codename='view_reconciliation',
name='Can view reconciliation'
)
def view(self, request: HttpRequest) -> HttpResponse:
return self.render(request=request, form=ReconcileForm())
class CustomAdminSite(ChassisAdminSiteMixin, AdminSite):
chassis_modal_classes = (ReconcileModal,)
PermissionAdminModal регистрирует свой PermissionOption и проверяет его как
при построении контекста trigger, так и при обработке GET или POST fragment
endpoint. Используйте AdminModal напрямую, если видимость требует своей
реализации has_view_permission().
Отрисовка trigger
Загрузите chassis_admin в любом Admin-шаблоне:
{% load chassis_admin %}
{% chassis_modal_trigger "reconcile" "Open reconciliation" "fa-solid fa-scale-balanced" %}
Необязательный четвёртый аргумент задаёт CSS-класс trigger. Если modal недоступен текущему пользователю, trigger не выводится.
Дочерний пункт dropdown в navbar может открыть то же окно: верните
AdminNavbarChildItemDTO с opens_modal=True и URL modal.
Fragment-шаблон и формы
Расширьте общий fragment и отметьте форму для асинхронной отправки:
{% extends "admin/chassis/modal.html" %}
{% block chassis_modal_body %}
<p class="chassis-modal-description">Review the data before continuing.</p>
{% include "admin/chassis/modal_form_errors.html" %}
<form method="post" action="{{ chassis_modal.get_url }}" data-chassis-modal-form>
{% csrf_token %}
{{ form.as_p }}
<div class="chassis-modal-actions">
<button type="button" data-chassis-modal-close>Cancel</button>
<button type="submit">Continue</button>
</div>
</form>
{% endblock %}
После успешного POST используйте AdminModal.redirect(url). Chassis выполнит
переход без промежуточного запроса страницы и сохранит Django messages.
close_on_backdrop и close_on_escape по умолчанию равны True и
настраиваются независимо. Размер оболочки и прокручиваемых таблиц ограничен
viewport браузера.
Контракт безопасности
Modal endpoint оборачиваются в AdminSite.admin_view(), требуют заголовок
X-Chassis-Modal: 1 и повторно вызывают has_view_permission() на каждом
запросе. Поэтому прямое обращение к endpoint возвращает HTTP 400, а не
отдельную Admin-страницу.