- Добавлен отчет о рефакторинге хранилища медиафайлов - Добавлено сравнение веток feature/django-filer-documents и develop - Добавлен аудит frontend документов - Добавлен отчет об очистке types, cabinets и dashboard
9.1 KiB
Рефакторинг структуры хранения медиа-файлов
Дата: 5 марта 2026
Статус: ✅ Завершено
🎯 Цели
Переход от хеш-структуры django-filer к читаемой структуре с организацией по датам.
📁 Было (deprecated)
media/filer_public/
├── 07/28/07286222-01c2-415c-ad2f-fc0ee3eb13f0/ ← Нечитаемая хеш-структура
├── 2a/cd/2acdaf8f-b428-42d6-aaf6-b9b63353e836/
└── ...
Проблемы старой структуры:
- ❌ Невозможно найти файл вручную
- ❌ Сложно организовать архивацию
- ❌ Нет ясности по периодам хранения
- ❌ Усложняет бэкапы по датам
📁 Стало (new)
media/
├── documents/
│ ├── public/2026/03/05/ ← Публичные документы по дате
│ ├── private/2026/03/05/ ← Приватные документы по дате
│ ├── public_thumbnails/ ← Превью публичных документов
│ └── private_thumbnails/ ← Превью приватных документов
├── avatars/ ← Аватарки пользователей
├── chat_attachments/2026/03/05/ ← Вложения мессенджера
└── temp/ ← Временные файлы
Преимущества новой структуры:
- ✅ Читаемые пути:
documents/public/2026/03/05/contract.pdf - ✅ Простая архивация: перемещение старых папок (например,
2024/) - ✅ Удобные бэкапы: легко выбрать период
- ✅ Естественная организация: по дате загрузки
🔧 Изменения в коде
1. Django settings.py
Было:
FILER_STORAGES = {
'public': {
'UPLOAD_TO': 'filer.utils.generate_filename.randomized',
'UPLOAD_TO_PREFIX': '%Y/%m', # Не работало правильно
}
}
Стало:
FILER_STORAGES = {
'public': {
'main': {
'ENGINE': 'filer.storage.PublicFileSystemStorage',
'OPTIONS': {
'location': os.path.join(MEDIA_ROOT, 'documents/public/'),
'base_url': '/media/documents/public/',
},
'UPLOAD_TO': 'filer.utils.generate_filename.by_date', # ← Ключевое изменение
},
'thumbnails': {
'ENGINE': 'filer.storage.PublicFileSystemStorage',
'OPTIONS': {
'location': os.path.join(MEDIA_ROOT, 'documents/public_thumbnails/'),
'base_url': '/media/documents/public_thumbnails/',
},
},
},
'private': {
'main': {
'ENGINE': 'filer.storage.PrivateFileSystemStorage',
'OPTIONS': {
'location': os.path.join(MEDIA_ROOT, 'documents/private/'),
'base_url': '/smedia/documents/private/',
},
'UPLOAD_TO': 'filer.utils.generate_filename.by_date', # ← Ключевое изменение
},
'thumbnails': {
'ENGINE': 'filer.storage.PrivateFileSystemStorage',
'OPTIONS': {
'location': os.path.join(MEDIA_ROOT, 'documents/private_thumbnails/'),
'base_url': '/smedia/documents/private_thumbnails/',
},
},
},
}
Ключевые изменения:
randomized→by_date- функция генерации путей- Организация:
YYYY/MM/DD/filename.ext - Раздельные пути для public/private
2. URL конфигурация (urls.py)
Было:
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Стало:
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Причина: В production статика раздается через Nginx, не Django.
3. .gitignore
Добавлено:
backend/media/*
!backend/media/.gitkeep
!backend/media/*/
!backend/media/*/.gitkeep
!backend/media/*/*/
!backend/media/*/*/.gitkeep
Результат: Git отслеживает структуру папок (через .gitkeep), но игнорирует загруженные файлы.
🧪 Тестирование
Тест создания файла
from django.core.files.base import ContentFile
from filer.models import File
test_content = ContentFile(b"Test document content", name="test_document.txt")
test_file = File.objects.create(
original_filename="test_document.txt",
file=test_content
)
print(test_file.file.path)
# Результат: /backend/media/documents/private/2026/03/05/test_document.txt
print(test_file.file.url)
# Результат: /smedia/documents/private/2026/03/05/test_document.txt
Результаты
✅ Путь корректный: documents/private/2026/03/05/test_document.txt
✅ Дата в пути: 2026/03/05 (YYYY/MM/DD)
✅ URL правильный: /smedia/documents/private/2026/03/05/test_document.txt
✅ Django check: 0 ошибок
📋 Management команда
Создана команда для миграции старых файлов:
python manage.py migrate_documents_storage --dry-run # Предпросмотр
python manage.py migrate_documents_storage # Выполнить миграцию
Статус миграции:
- Проверено: 34 записи в БД
- Физически файлов: 0 (старые файлы уже удалены)
- Миграция не требуется
Файл: backend/documents/management/commands/migrate_documents_storage.py
📚 Документация
Создана документация со структурой и инструкциями:
- Файл:
backend/media/README.md - Разделы:
- Структура директорий
- Настройка FILER_STORAGES
- Инструкции по миграции
- Безопасность (public vs private)
- Конфигурация Nginx для production
🧹 Очистка
Удалены устаревшие структуры:
rm -rf backend/media/filer_public/ # Старая хеш-структура
rm -rf backend/media/documents/private/%Y/ # Тестовые папки
До очистки:
- 47 директорий
- 10 тестовых файлов в filer_public/
После очистки:
- 14 директорий (чистая структура)
- .gitkeep файлы во всех пустых папках
🎯 Итоги
✅ Выполнено
- ✅ Настроена структура
documents/public/иdocuments/private/ - ✅ Изменен генератор путей на
by_date(YYYY/MM/DD) - ✅ Обновлена конфигурация Django (settings.py)
- ✅ Исправлен URL routing для production
- ✅ Настроен .gitignore для media/
- ✅ Создана management команда миграции
- ✅ Написана документация (README.md)
- ✅ Протестировано создание файлов
- ✅ Удалены старые структуры
- ✅ Созданы .gitkeep файлы
📊 Метрики
- Файлов изменено: 4 (
settings.py,urls.py,.gitignore,README.md) - Файлов создано: 2 (management команда + отчет)
- Директорий очищено: 33 (из 47 осталось 14)
- Ошибок Django check: 0
- TypeScript ошибок: 0 (не затронуто)
🚀 Готовность к production
- ✅ Nginx конфигурация описана в README.md
- ✅ URL routing работает корректно
- ✅ Безопасность (public/private разделение)
- ✅ Структура масштабируемая
- ✅ Бэкапы легко организовать по датам
📌 Следующие шаги (опционально)
- Настройка Nginx - для раздачи static/media в production
- Автоочистка - удаление старых файлов (например, старше 1 года)
- S3 интеграция - для облачного хранения (если требуется масштабирование)
- Мониторинг - отслеживание размера media/ директории
🔗 Связанные документы
- backend/media/README.md - Руководство по структуре
backend/documents/management/commands/migrate_documents_storage.py- Команда миграцииbackend/eusrr_backend/settings.py- Конфигурация FILER_STORAGES