# Система оценки качества фотографий товаров - ФАЗА 1 ✅ ЗАВЕРШЕНА ## Что реализовано ### 1. Конфигурация в settings.py ```python IMAGE_QUALITY_LEVELS = { 'excellent': 0.95, # >= 95% от max (если max=2160 → >= 2052px) 'good': 0.70, # >= 70% от max (если max=2160 → >= 1512px) 'acceptable': 0.40, # >= 40% от max (если max=2160 → >= 864px) 'poor': 0.20, # >= 20% от max (если max=2160 → >= 432px) # < 20% = very_poor } IMAGE_QUALITY_LABELS = { 'excellent': {'label': 'Отлично', 'color': 'success', 'recommendation': '...'}, 'good': {'label': 'Хорошо', 'color': 'info', 'recommendation': '...'}, 'acceptable': {'label': 'Приемлемо', 'color': 'warning', 'recommendation': '...'}, 'poor': {'label': 'Плохо', 'color': 'danger', 'recommendation': '...'}, 'very_poor': {'label': 'Очень плохо', 'color': 'danger', 'recommendation': '...'}, } ``` ### 2. Валидатор (validators/image_validators.py) **Полностью гибкий валидатор, который:** - Динамически читает max размеры из `IMAGE_PROCESSING_CONFIG` - Вычисляет пороги как процент от максимума - Определяет уровень качества для любого размера изображения **Функции:** ```python # Получить максимальный размер из конфиг get_max_dimension_from_config() → 2160 # Определить качество на основе размеров get_image_quality_level(width, height) → ('good', False) # Получить информацию о уровне get_quality_info('excellent') → {label, color, recommendation, ...} # Валидация фото для UI validate_product_image(file) → {valid, width, height, quality_level, message, error} ``` **Пример работы:** ```python # Если вы загружаете фото 546×546 (а max=2160): quality_level, needs_update = get_image_quality_level(546, 546) # Результат: ('acceptable', False) # Расчет: 546/2160 = 0.253 (25.3%) # 25.3% >= 40%? Нет, >= 20%? Да → poor # На самом деле: 25.3% >= 40%? Нет, но >= 20%? Да → poor # Хм, давайте пересчитаем: # - excellent: 546/2160 = 0.253 >= 0.95? Нет # - good: 0.253 >= 0.70? Нет # - acceptable: 0.253 >= 0.40? Нет # - poor: 0.253 >= 0.20? Да ✓ # Результат: ('poor', True) ← требует обновления ``` ### 3. Модели (ProductPhoto, ProductKitPhoto, ProductCategoryPhoto) **Добавлены новые поля:** ```python quality_level = CharField( choices=[ ('excellent', 'Отлично (>= 2052px)'), ('good', 'Хорошо (1512-2051px)'), ('acceptable', 'Приемлемо (864-1511px)'), ('poor', 'Плохо (432-863px)'), ('very_poor', 'Очень плохо (< 432px)'), ], default='acceptable', db_index=True, ) quality_warning = BooleanField( default=False, # True для poor и very_poor db_index=True, ) ``` **Индексы для быстрого поиска:** ```python indexes = [ models.Index(fields=['quality_level']), models.Index(fields=['quality_warning']), models.Index(fields=['quality_warning', 'product']), # Товары требующие обновления ] ``` ### 4. Image Processor (image_processor.py) **Обновлен метод process_image:** ```python def process_image(image_file, base_path, entity_id, photo_id): # Раньше возвращал: # {'original': '...', 'large': '...', 'medium': '...', 'thumbnail': '...'} # Теперь возвращает дополнительно: { 'original': '...', 'large': '...', 'medium': '...', 'thumbnail': '...', 'width': 1920, 'height': 1080, 'quality_level': 'excellent', 'quality_warning': False, } ``` ### 5. Сохранение фото (photos.py -> save()) **Автоматическое определение качества:** - При создании нового фото → вычисляет quality_level и quality_warning - При обновлении фото → пересчитывает качество - Сохраняет все три поля atomically в БД ## Как это работает (пример) ### Сценарий: Загрузка фото 546×546px 1. **Пользователь загружает фото** через форму продукта 2. **Вызывается ProductPhoto.save()** 3. **ImageProcessor.process_image()** обрабатывает фото: - Открывает изображение, получает размеры 546×546 - **Вызывает get_image_quality_level(546, 546)** - Вычисляет: max=2160 (из settings), percent=546/2160=0.253 - Сравнивает с пороги: 0.253 >= 0.20? **Да** → 'poor' - Возвращает: ('poor', True) - Сохраняет все размеры (original, large, medium, thumb) - Возвращает обработанные пути + quality info 4. **ProductPhoto.save()** получает результат: ```python processed_paths = { 'original': 'products/2/7/original.jpg', 'quality_level': 'poor', 'quality_warning': True, } ``` 5. **Сохраняет в БД:** ```python photo.image = 'products/2/7/original.jpg' photo.quality_level = 'poor' photo.quality_warning = True photo.save() ``` ### Результат в БД: ``` ProductPhoto: - id: 7 - product_id: 2 - image: products/2/7/original.jpg - quality_level: 'poor' 🔴 - quality_warning: True ← Требует обновления! - order: 0 ``` ## Гибкость конфигурации ### Пример 1: Вы изменили max_width с 2160 на 3000 ```python # В settings.py IMAGE_PROCESSING_CONFIG = { 'formats': { 'original': { 'max_width': 3000, # Было 2160 'max_height': 3000, } } } # Система АВТОМАТИЧЕСКИ пересчитает: # excellent: 0.95 * 3000 = 2850px # good: 0.70 * 3000 = 2100px # acceptable: 0.40 * 3000 = 1200px # poor: 0.20 * 3000 = 600px # Код не менялся! ✓ ``` ### Пример 2: Вы изменили пороги качества ```python # Было: IMAGE_QUALITY_LEVELS = { 'excellent': 0.95, 'good': 0.70, } # Стало: IMAGE_QUALITY_LEVELS = { 'excellent': 0.90, # Жестче 'good': 0.60, # Жестче } # Система АВТОМАТИЧЕСКИ переклассифицирует новые загрузки # Старые фото останутся как есть (можно переклассифицировать через management команду) ``` ## Что дальше (Фаза 2) После создания миграций, нужно реализовать: ### Phase 2: Admin интерфейс 1. **Фильтры в админке**: - По качеству (excellent, good, acceptable, poor, very_poor) - Товары требующие обновления фото (quality_warning=True) 2. **Визуальные индикаторы**: - Цветные иконки в списке товаров (🟢 Отлично, 🟡 Хорошо, 🟠 Приемлемо, 🔴 Плохо) - Action для поиска товаров требующих обновления 3. **Админ-дисплеи**: - Форматирование качества в таблицах - Цветные бэджи ### Phase 3: Фронтенд UI 1. **Форма загрузки**: - Preview фото с индикатором качества - Сообщение о рекомендации - Информация о размерах 2. **Список товаров**: - Иконка качества для каждого фото - Подсказка при наведении ## Структура файлов (после миграции) ``` myproject/ ├── myproject/ │ └── settings.py ← IMAGE_QUALITY_LEVELS, IMAGE_QUALITY_LABELS ├── products/ │ ├── models/ │ │ └── photos.py ← ProductPhoto, ProductKitPhoto, ProductCategoryPhoto с новыми полями │ ├── validators/ │ │ └── image_validators.py ← Новый файл! Вся гибкая логика │ ├── utils/ │ │ └── image_processor.py ← Обновлен process_image() │ └── migrations/ │ └── XXXX_add_photo_quality_assessment.py ← НУЖНА ВАША МИГРАЦИЯ! ``` ## Коммит ``` 622e17a feat: Реализовать систему оценки качества фотографий товаров (Фаза 1) ``` ## Следующие шаги 1. **Создать миграцию** через: ```bash python manage.py makemigrations products --name add_photo_quality_assessment ``` 2. **Применить миграцию**: ```bash python manage.py migrate ``` 3. **Протестировать вычисление качества**: ```python python manage.py shell >>> from products.validators.image_validators import get_image_quality_level >>> get_image_quality_level(546, 546) ('poor', True) >>> get_image_quality_level(2160, 2160) ('excellent', False) ``` 4. **Загрузить фото к товару** и проверить что quality_level и quality_warning автоматически заполнены в админке 5. **Приступить к Фазе 2** - реализовать admin интерфейс --- **Фаза 1 завершена! 🎉 Система полностью готова к расширению.**