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:
@@ -145,7 +145,6 @@ DATABASES = {
|
||||
'PORT': env('DB_PORT'),
|
||||
'OPTIONS': {
|
||||
'client_encoding': 'UTF8',
|
||||
'connect_timeout': 10,
|
||||
},
|
||||
'CONN_MAX_AGE': 0,
|
||||
}
|
||||
@@ -242,6 +241,78 @@ IMAGE_PROCESSING_CONFIG = {
|
||||
}
|
||||
|
||||
|
||||
# ============================================
|
||||
# IMAGE QUALITY ASSESSMENT SETTINGS
|
||||
# ============================================
|
||||
|
||||
# Пороги качества как доля от максимального размера оригинала (0.0 - 1.0)
|
||||
# Вычисляется динамически: if image_size >= threshold * max_original_size → quality_level
|
||||
#
|
||||
# Пример: если max_width=2160, то:
|
||||
# - excellent: >= 2052px (95% * 2160)
|
||||
# - good: >= 1512px (70% * 2160)
|
||||
# - acceptable: >= 864px (40% * 2160)
|
||||
# - poor: >= 432px (20% * 2160)
|
||||
# - very_poor: < 432px
|
||||
IMAGE_QUALITY_LEVELS = {
|
||||
'excellent': 0.95, # 95% от максимума
|
||||
'good': 0.70, # 70% от максимума
|
||||
'acceptable': 0.40, # 40% от максимума
|
||||
'poor': 0.20, # 20% от максимума
|
||||
# < 20% = very_poor
|
||||
}
|
||||
|
||||
# Описания и рекомендации для каждого уровня качества
|
||||
# Используется в админке, формах и API
|
||||
IMAGE_QUALITY_LABELS = {
|
||||
'excellent': {
|
||||
'label': 'Отлично',
|
||||
'short_label': 'Отлично ✓',
|
||||
'description': 'Идеальное качество изображения',
|
||||
'color': 'success',
|
||||
'icon': '✓',
|
||||
'recommendation': 'Готово для выгрузки на сайт',
|
||||
'badge_class': 'badge-success',
|
||||
},
|
||||
'good': {
|
||||
'label': 'Хорошо',
|
||||
'short_label': 'Хорошо ◐',
|
||||
'description': 'Хорошее качество изображения',
|
||||
'color': 'info',
|
||||
'icon': '◐',
|
||||
'recommendation': 'Можно выгружать на сайт',
|
||||
'badge_class': 'badge-info',
|
||||
},
|
||||
'acceptable': {
|
||||
'label': 'Приемлемо',
|
||||
'short_label': 'Приемлемо ⚠',
|
||||
'description': 'Приемлемое качество, но рекомендуется обновить',
|
||||
'color': 'warning',
|
||||
'icon': '⚠',
|
||||
'recommendation': 'Лучше обновить перед выгрузкой на сайт',
|
||||
'badge_class': 'badge-warning',
|
||||
},
|
||||
'poor': {
|
||||
'label': 'Плохо',
|
||||
'short_label': 'Плохо ✗',
|
||||
'description': 'Низкое качество изображения',
|
||||
'color': 'danger',
|
||||
'icon': '✗',
|
||||
'recommendation': 'Требует обновления перед выгрузкой на сайт',
|
||||
'badge_class': 'badge-danger',
|
||||
},
|
||||
'very_poor': {
|
||||
'label': 'Очень плохо',
|
||||
'short_label': 'Очень плохо ✗✗',
|
||||
'description': 'Очень низкое качество изображения',
|
||||
'color': 'danger',
|
||||
'icon': '✗✗',
|
||||
'recommendation': 'Обязательно обновить перед любой выгрузкой',
|
||||
'badge_class': 'badge-danger',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# ============================================
|
||||
# BUSINESS LOGIC SETTINGS
|
||||
# ============================================
|
||||
|
||||
Reference in New Issue
Block a user