13 KiB
Руководство: Requests Detail View
Дата создания: 26 декабря 2025 г. Версия: 1.0 Статус: ✅ Готово к использованию
📖 Описание функции
Requests Detail View - это полнофункциональное модальное окно для просмотра деталей заявления с возможностью:
- 📋 Просмотра полной информации о заявлении
- 💬 Добавления и удаления комментариев
- ✅ Изменения статуса (для администраторов)
- 🎨 Интуитивного пользовательского интерфейса
🎯 Основные компоненты
1. Backend
RequestDetailView (views_front.py)
class RequestDetailView(LoginRequiredMixin, TemplateView):
"""Детальный просмотр заявления с комментариями"""
template_name = "requests_app/request_detail.html"
def get_context_data(self, pk: int, **kwargs):
# Загружает заявление и комментарии из API
# Проверяет права доступа
# Форматирует данные для отображения
URL: /requests/{id}/
Контекст:
request_obj- данные заявленияcomments- список комментариевcan_process- может ли пользователь менять статусerror- сообщение об ошибке (если есть)
API Endpoints
GET /api/v1/requests/{id}/ Получить полные данные заявления
{
"id": 123,
"type": "vacation",
"status": "pending",
"title": "Отпуск на неделю",
"comment": "Хочу взять отпуск...",
"created_at": "2025-12-26T10:00:00Z",
"date_from": "2026-01-01",
"date_to": "2026-01-07"
}
GET /api/v1/requests/{id}/comments/ Получить список комментариев
{
"count": 2,
"results": [
{
"id": 1,
"text": "Согласен",
"author": {"id": 1, "full_name": "Иван Петров"},
"created_at": "2025-12-26T11:00:00Z"
}
]
}
POST /api/v1/requests/{id}/comments/ Добавить комментарий
{
"text": "Новый комментарий"
}
DELETE /api/v1/requests/{id}/comments/{comment_id}/ Удалить комментарий (только для автора)
POST /api/v1/requests/{id}/approve/ Одобрить заявление (требует права)
POST /api/v1/requests/{id}/reject/ Отклонить заявление (требует права)
POST /api/v1/requests/{id}/cancel/ Отменить заявление
2. Frontend
requestDetail.js (JavaScript модуль)
// Инициализация на странице
const detailModal = initRequestDetailModal();
// Открытие модали
detailModal.open(requestId);
// Закрытие модали
detailModal.close();
Класс RequestDetailModal:
open(requestId)- открыть модальное окноloadData(requestId)- загрузить данные через AJAXhandleCommentSubmit(e)- добавить комментарийhandleDeleteComment(e)- удалить комментарийhandleStatusChange(e)- изменить статусattachEventListeners()- подключить обработчики событийupdateCommentsCount()- обновить счетчик комментариевinitEmojiPicker()- инициализировать emoji picker
3. Шаблоны
request_detail.html
Основной шаблон для отображения деталей заявления
- Информация о заявлении (тип, статус, даты)
- Список комментариев
- Форма добавления комментария
- Форма изменения статуса (для администраторов)
request_list_full.html
Главная страница списка заявлений
- Таблица заявлений
- Модальное окно для деталей
- Фильтры и поиск
- Пагинация
🚀 Использование
Для пользователей
- Открыть страницу заявлений:
/requests/ - Кликнуть на заявление в таблице
- В модали можно:
- Просмотреть все детали
- Прочитать и добавить комментарии
- Изменить статус (если администратор)
- Закрыть модаль: кнопка X или клик вне модали
Для разработчиков
Интеграция в другую страницу
<!-- Подключить JavaScript модуль -->
<script type="module">
import { initRequestDetailModal } from '/static/js/modules/requestDetail.js';
// Инициализировать модаль
const modal = initRequestDetailModal();
// Открыть при клике
document.getElementById('my-btn').addEventListener('click', () => {
modal.open(requestId);
});
</script>
<!-- Добавить HTML структуру модали -->
<div class="modal" id="requestDetailModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Детали заявления</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="requestDetailContent">
<!-- Содержимое загружается здесь -->
</div>
</div>
</div>
</div>
Кастомизация
Изменение ID модального окна:
const modal = new RequestDetailModal('myModalId', 'myContentId');
🔒 Безопасность
Проверки прав доступа
-
Просмотр заявления:
- Автор может видеть свою заявку
- Адресат может видеть адресованную ему заявку
- Администратор может видеть любую заявку
- Другой пользователь получит 403
-
Добавление комментария:
- Требует аутентификации (402 если нет)
- Автоматическая привязка к текущему пользователю
-
Удаление комментария:
- Может удалить только автор комментария
- Администраторы также могут удалять (проверка на backend)
-
Изменение статуса:
- Требует права
requests_app.can_process_requests - Видно только администраторам
- API проверяет права на каждый запрос
- Требует права
Защита от атак
- CSRF: Все POST/DELETE запросы используют CSRF токен
- XSS: Текст комментариев экранируется в шаблоне
- SQL Injection: Использование Django ORM
- Rate Limiting: Защита от спама (настраивается в settings)
🛠️ Техническая информация
Зависимости
Backend:
- Django 5.2.4+
- Django REST Framework
- Django Channels (для будущих WebSocket уведомлений)
Frontend:
- Bootstrap 5
- Vanilla JavaScript ES6+
- emoji-picker (опционально)
Структура файлов
backend/
├── requests_app/
│ ├── views_front.py # RequestDetailView
│ ├── urls_front.py # URL маршруты
│ ├── notification_signals.py # Уведомления
│ └── models.py # Модель Request
├── api/v1/
│ └── requests_app/
│ └── views.py # RequestViewSet (API)
├── templates/requests_app/
│ ├── request_detail.html # Шаблон деталей
│ └── request_list_full.html # Шаблон списка
└── static/js/modules/
└── requestDetail.js # JavaScript модуль
Интеграция с уведомлениями
Все события автоматически создают уведомления:
- Создание заявления: всем адресатам
- Добавление комментария: создателю и адресатам
- Смена статуса: создателю заявления
URL в уведомлениях: /requests/{id}/
📋 Примеры использования
Пример 1: Просмотр заявления
HTML:
<button onclick="detailModal.open(123)">Просмотреть</button>
Результат: Модальное окно с полной информацией о заявлении #123
Пример 2: Добавление комментария в модали
Форма автоматически обрабатывает:
- Валидацию текста (не пусто)
- Отправку через API
- Обновление списка комментариев
- Обновление счетчика
Пример 3: Изменение статуса
Только для администраторов видна форма:
<form class="request-status-form">
<select name="status">
<option value="approved">✓ Одобрить</option>
<option value="rejected">✗ Отклонить</option>
<option value="cancelled">⊗ Отменить</option>
</select>
<button>Применить</button>
</form>
🐛 Решение проблем
Проблема: Модаль не открывается
Решение:
- Проверить консоль браузера (F12) на ошибки
- Убедиться что элемент с id="requestDetailModal" существует
- Проверить что requestDetail.js загружен
Проблема: Комментарии не загружаются
Решение:
- Проверить API endpoint: GET
/api/v1/requests/{id}/comments/ - Проверить права доступа (403?)
- Проверить CORS в браузере
Проблема: Нельзя менять статус
Решение:
- Проверить что вы администратор (can_process=true)
- Проверить что заявление в статусе "pending"
- Проверить права на backend:
can_process_requests
Проблема: Emoji picker не работает
Решение:
- Подключить библиотеку emoji-picker
- Проверить что форма имеет класс
message-field - Проверить консоль на ошибки загрузки модуля
📈 Статистика производительности
- Загрузка модали: ~500ms (в зависимости от сети)
- Добавление комментария: ~200ms
- Изменение статуса: ~300ms
- Размер модуля requestDetail.js: ~8 KB
🔄 История версий
v1.0 (26 декабря 2025)
- ✅ Первая версия
- ✅ Полная система комментариев
- ✅ Управление статусом
- ✅ Поддержка emoji
- ✅ Обработка ошибок
Планируемые улучшения (v2.0)
- 🔄 WebSocket для уведомлений в реальном времени
- 🔄 Редактирование комментариев
- 🔄 Упоминания (@username)
- 🔄 Вложения в комментариях
- 🔄 Поиск по комментариям
📞 Поддержка и обратная связь
Для сообщений об ошибках или предложений по улучшению:
- Создать Issue в GitHub
- Описать проблему/предложение
- Приложить скриншоты или видео если применимо
Дата обновления: 26 декабря 2025 г. Версия документации: 1.0 Автор: Development Team