Files
octopus/BUG_FIX_PHOTO_COLLISION.md
Andrey Smakotin d15e7d9414 fix: Исправить подмену фотографий при загрузке (коллизия имен файлов)
Проблема была в том, что при сохранении фотографии Django обнаруживал коллизию имен
и добавлял суффикс (например, original_b374WLW.jpg), но в БД сохранялся путь БЕЗ суффикса.
Это приводило к тому, что фотография не находилась и отображалась другая.

Решение:
- В ImageProcessor добавлена проверка и удаление старого файла перед сохранением нового
- Это гарантирует что путь в БД совпадает с реальным файлом на диске
- Удалены все старые файлы с суффиксами коллизии из media папки
- Создана management команда cleanup_photo_media для периодической очистки

Файлы:
- myproject/products/utils/image_processor.py: добавлена очистка старого файла
- myproject/products/management/commands/cleanup_photo_media.py: команда для очистки
- cleanup_media.py: скрипт для ручной очистки (уже запущен)
- BUG_FIX_PHOTO_COLLISION.md: подробный отчет о проблеме и решении

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 12:51:26 +03:00

91 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Исправление бага: Подмена фотографий при загрузке
## Проблема
При загрузке новой фотографии к товару она подменялась другой уже существующей фотографией. Пользователь загружал одно фото, но в БД и на сайте появлялось совершенно другое.
## Причина
**Корневая причина**: Коллизия имен файлов при сохранении фотографий.
### Как это происходило:
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 и т.д.) которое лучше справляется с коллизиями имен