Files
octopus/PHOTO_QUALITY_SYSTEM_PHASE1.md
Andrey Smakotin 6c8af5ab2c fix: Улучшения системы ценообразования комплектов
Исправлены 4 проблемы:
1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice
2. Отображение actual_price в Select2 вместо обычной цены
3. Количество по умолчанию = 1 для новых форм компонентов
4. Auto-select текста при клике на поле количества для удобства редактирования

Изменённые файлы:
- products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1
- products/templates/includes/select2-product-init.html: обновлена formatSelectResult
- products/templates/productkit_create.html: добавлен focus handler для auto-select
- products/templates/productkit_edit.html: добавлен focus handler для auto-select

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 19:04:03 +03:00

9.9 KiB
Raw Blame History

Система оценки качества фотографий товаров - ФАЗА 1 ЗАВЕРШЕНА

Что реализовано

1. Конфигурация в settings.py

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
  • Вычисляет пороги как процент от максимума
  • Определяет уровень качества для любого размера изображения

Функции:

# Получить максимальный размер из конфиг
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}

Пример работы:

# Если вы загружаете фото 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)

Добавлены новые поля:

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,
)

Индексы для быстрого поиска:

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:

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() получает результат:
    processed_paths = {
        'original': 'products/2/7/original.jpg',
        'quality_level': 'poor',
        'quality_warning': True,
    }
    
  5. Сохраняет в БД:
    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

# В 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: Вы изменили пороги качества

# Было:
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. Создать миграцию через:

    python manage.py makemigrations products --name add_photo_quality_assessment
    
  2. Применить миграцию:

    python manage.py migrate
    
  3. Протестировать вычисление качества:

    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 завершена! 🎉 Система полностью готова к расширению.