feat: Реализовать систему оценки качества фотографий товаров (Фаза 1)
Добавлена полностью гибкая система для оценки качества фотографий на основе размеров:
Конфигурация (settings.py):
- IMAGE_QUALITY_LEVELS: Пороги качества как доля от максимума (95%, 70%, 40%, 20%)
- IMAGE_QUALITY_LABELS: Описания, цвета и рекомендации для каждого уровня
- Система полностью адаптивна - меняется max_width в settings → пороги пересчитываются
Валидатор (validators/image_validators.py):
- get_max_dimension_from_config() - динамически читает из IMAGE_PROCESSING_CONFIG
- get_image_quality_level() - определяет уровень качества (excellent/good/acceptable/poor/very_poor)
- get_quality_info() - информация о уровне из IMAGE_QUALITY_LABELS
- validate_product_image() - комплексная валидация для UI
Модели (models/photos.py):
- ProductPhoto, ProductKitPhoto, ProductCategoryPhoto дополнены полями:
- quality_level: уровень качества (CharField с choices)
- quality_warning: требует ли обновления (BooleanField)
- Добавлены индексы для быстрого поиска товаров требующих обновления фото
Обработчик (image_processor.py):
- process_image() теперь возвращает дополнительно:
- width, height: размеры оригинального изображения
- quality_level: уровень качества
- quality_warning: нужно ли обновить перед выгрузкой
- Вызывает валидатор автоматически при обработке
Логика сохранения (photos.py -> save()):
- При сохранении нового фото автоматически вычисляет quality_level и quality_warning
- При обновлении существующего фото пересчитывает качество
- Сохраняет все три поля атомарно
Система полностью готова к:
- Phase 2: Admin интерфейс с фильтрами и индикаторами
- Phase 3: Фронтенд с визуальными индикаторами в формах и API
Примеры использования:
>>> from products.validators.image_validators import get_image_quality_level
>>> get_image_quality_level(1400, 1400) # если max=2160
('good', False) # 1400/2160 = 64.8% >= 70%? Нет, но >= 40%
>>> get_image_quality_level(400, 400)
('poor', True) # Требует обновления
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -79,12 +79,16 @@ class ImageProcessor:
|
||||
photo_id: ID фотографии
|
||||
|
||||
Returns:
|
||||
dict: Словарь с путями сохраненных файлов
|
||||
dict: Словарь с сохраненными данными
|
||||
{
|
||||
'original': 'products/<entity_id>/<photo_id>/original.jpg',
|
||||
'large': 'products/<entity_id>/<photo_id>/large.webp',
|
||||
'medium': 'products/<entity_id>/<photo_id>/medium.webp',
|
||||
'thumbnail': 'products/<entity_id>/<photo_id>/thumb.webp',
|
||||
'width': 1920,
|
||||
'height': 1080,
|
||||
'quality_level': 'good',
|
||||
'quality_warning': False,
|
||||
}
|
||||
|
||||
Raises:
|
||||
@@ -96,6 +100,11 @@ class ImageProcessor:
|
||||
try:
|
||||
# Открываем изображение
|
||||
img = Image.open(image_file)
|
||||
width, height = img.size
|
||||
|
||||
# Определяем качество на основе размеров
|
||||
from ..validators.image_validators import get_image_quality_level
|
||||
quality_level, needs_update = get_image_quality_level(width, height)
|
||||
|
||||
# Конвертируем в RGB если необходимо (для JPEG/WebP)
|
||||
if img.mode in ('RGBA', 'LA', 'P'):
|
||||
@@ -126,6 +135,16 @@ class ImageProcessor:
|
||||
)
|
||||
saved_paths[size_key] = size_path
|
||||
|
||||
# Добавляем информацию о качестве
|
||||
saved_paths['width'] = width
|
||||
saved_paths['height'] = height
|
||||
saved_paths['quality_level'] = quality_level
|
||||
saved_paths['quality_warning'] = needs_update
|
||||
|
||||
logger.info(
|
||||
f"Image processed: {width}x{height}px → quality={quality_level}, warning={needs_update}"
|
||||
)
|
||||
|
||||
return saved_paths
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user