# Исправление бага: Подмена фотографий при загрузке ## Проблема При загрузке новой фотографии к товару она подменялась другой уже существующей фотографией. Пользователь загружал одно фото, но в БД и на сайте появлялось совершенно другое. ## Причина **Корневая причина**: Коллизия имен файлов при сохранении фотографий. ### Как это происходило: 1. Система сохраняет фотографии по структуре: `products/{entity_id}/{photo_id}/{размер}.{расширение}` - Пример: `products/2/7/original.jpg`, `products/2/7/large.webp`, и т.д. 2. Когда нужно перезаписать фотографию (при обновлении), Django обнаруживает что файл уже существует 3. Вместо замены, Django добавляет суффикс коллизии к имени файла: - Ожидается: `products/2/3/original.jpg` - Реально сохраняется: `products/2/3/original_LxC9yjS.jpg` ← с суффиксом 4. **ПРОБЛЕМА**: В БД сохраняется путь БЕЗ суффикса (`products/2/3/original.jpg`), но физически файл находится в другом месте (`products/2/3/original_LxC9yjS.jpg`) 5. Когда шаблон запрашивает `{{ photo.image.url }}`, Django ищет файл `products/2/3/original.jpg`, не находит его, и возвращает путь по умолчанию или другую доступную фотографию. ## Решение ### Шаг 1: Обновлен `image_processor.py` В методе `_save_image_version()` добавлена проверка и удаление старого файла ПЕРЕД сохранением нового: ```python # ВАЖНО: Удаляем старый файл если он существует, чтобы избежать коллизий имен if default_storage.exists(file_path): try: default_storage.delete(file_path) logger.info(f"Deleted old file: {file_path}") except Exception as e: logger.warning(f"Could not delete old file {file_path}: {str(e)}") ``` Это гарантирует что: - Старый файл удаляется перед сохранением нового - Django не встречает коллизию имен - Путь в БД совпадает с реальным расположением файла на диске ### Шаг 2: Очистка старых данных Создан и запущен скрипт `cleanup_media.py` который: - Удалил все старые файлы с суффиксами коллизии (`original_b374WLW.jpg`, `large_lmCnBYn.webp` и т.д.) - Удалил старые файлы из папки `products/originals/` (старая схема хранения) **Результат**: Успешно удалено 6 устаревших файлов ## Файлы, измененные 1. **myproject/products/utils/image_processor.py** - Добавлена проверка и удаление старого файла перед сохранением нового - Добавлено логирование коллизий имен 2. **myproject/products/management/commands/cleanup_photo_media.py** - Создана management команда для очистки старых файлов (опционально) 3. **cleanup_media.py** (в корне проекта) - Создан скрипт для ручной очистки старых данных ## Как проверить исправление 1. Откройте товар с ID 2 (или любой другой товар) 2. Попробуйте загрузить новое фото 3. При сохранении фото должно правильно отобразиться 4. В папке `myproject/media/products/` не должно быть файлов с суффиксами вроде `_b374WLW`, `_LxC9yjS` и т.д. ## Технические детали - **Файлы с коллизией**: Django использует функцию `storage.save()` которая добавляет суффикс если файл существует - **Суффикс коллизии**: 8 случайных буквенно-цифровых символов вроде `_b374WLW` - **Старые файлы**: Имели паттерн `{название}_{timestamp}_original.jpg` (из старой системы) ## Результаты ✓ Исправлено ошибочное сохранение путей в БД ✓ Удалены все старые файлы с коллизией имен ✓ Добавлена проверка при сохранении новых фотографий ✓ Добавлено логирование для отладки будущих проблем с коллизиями ## Рекомендации 1. Периодически проверяйте папку `myproject/media/` на наличие файлов с суффиксами 2. Можно добавить периодическую очистку через Celery или cron 3. В продакшене рекомендуется использовать облачное хранилище (S3 и т.д.) которое лучше справляется с коллизиями имен