Files
octopus/myproject/products/views
Andrey Smakotin 48938db04f Implement M2M architecture for ConfigurableKitProduct variants with dynamic attribute selection
This commit introduces a complete refactoring of the variable product system:

1. **New Model**: ConfigurableKitOptionAttribute - M2M relationship between variants and attribute values
   - Replaces TextField-based attribute storage with proper database relationships
   - Ensures one value per attribute per variant through unique_together constraint
   - Includes indexes on both option and attribute fields for query performance

2. **Form Refactoring**:
   - Removed static 'attributes' field from ConfigurableKitOptionForm
   - Added dynamic field generation in __init__ based on parent attributes
   - Creates ModelChoiceField for each attribute (e.g., attribute_Длина, attribute_Упаковка)
   - Enhanced BaseConfigurableKitOptionFormSet validation to check all attributes are filled

3. **View Updates**:
   - Modified ConfigurableKitProductCreateView.form_valid() to save M2M relationships
   - Modified ConfigurableKitProductUpdateView.form_valid() with same logic
   - Uses transaction.atomic() for data consistency

4. **Template & JS Enhancements**:
   - Reordered form so attributes section appears before variants
   - Fixed template syntax: changed from field.name.startswith to "attribute_" in field.name
   - Updated JavaScript to dynamically generate attribute select fields when adding variants
   - Properly handles formset naming convention (options-{idx}-attribute_{name})

5. **Database Migrations**:
   - Created migration 0005 to alter ConfigurableKitOption.attributes to JSONField (for future use)
   - Created migration 0006 to add ConfigurableKitOptionAttribute model

6. **Tests**:
   - Added test_configurable_simple.py for model/form verification
   - Added test_workflow.py for complete end-to-end testing
   - All tests passing successfully

Features:
✓ All attributes required for each variant if defined on parent
✓ One value per attribute per variant (unique_together constraint)
✓ One default variant per product (formset validation)
✓ Dynamic form field generation based on parent attributes
✓ Atomic transactions for multi-part operations
✓ Proper error messages per variant number

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 20:04:22 +03:00
..

Структура модуля views

Файл products/views.py был разбит на несколько специализированных модулей для улучшения читаемости и поддерживаемости кода.

Статистика оптимизации

До рефакторинга:

  • Файлов: 1 (views.py)
  • Строк кода: 1202
  • Дублированный код: ~400 строк (12 функций управления фото + 3 функции обработки фото)

После рефакторинга:

  • Файлов: 7 модулей
  • Строк кода: 1284 (включая документацию)
  • Дублированный код: УСТРАНЁН
  • Экономия: ~400 строк дублированного кода заменены на универсальные функции

Структура модулей

1. __init__.py (112 строк)

Экспортирует все представления для обратной совместимости с urls.py. Позволяет использовать импорты вида: from products.views import ProductListView

2. utils.py (73 строки)

Утилиты для работы с фотографиями:

  • validate_photo() - валидация загружаемого фото
  • handle_photos() - УНИВЕРСАЛЬНАЯ функция обработки фото (заменяет 3 дублирующиеся функции)

3. photo_management.py (310 строк)

Универсальные функции управления фотографиями:

  • 4 базовые функции: generic_photo_delete(), generic_photo_set_main(), generic_photo_move_up(), generic_photo_move_down()
  • 12 оберток для Product, ProductKit и Category (заменяют 12 дублирующихся функций из оригинала)

Устранённое дублирование:

  • Было: 12 отдельных функций (по 4 для каждой модели)
  • Стало: 4 универсальные функции + 12 простых оберток

4. product_views.py (182 строки)

CRUD представления для товаров (Product):

  • ProductListView - список товаров с фильтрацией и поиском
  • ProductCreateView - создание товара
  • ProductDetailView - просмотр товара
  • ProductUpdateView - редактирование товара
  • ProductDeleteView - удаление товара

5. productkit_views.py (249 строк)

CRUD представления для комплектов (ProductKit):

  • ProductKitListView - список комплектов
  • ProductKitCreateView - создание комплекта с компонентами
  • ProductKitDetailView - просмотр комплекта
  • ProductKitUpdateView - редактирование комплекта
  • ProductKitDeleteView - удаление комплекта

6. category_views.py (280 строк)

CRUD представления для категорий (ProductCategory):

  • TreeItem - класс для элемента дерева категорий
  • ProductCategoryListView - иерархическое дерево категорий с товарами и комплектами
  • ProductCategoryCreateView - создание категории
  • ProductCategoryDetailView - просмотр категории
  • ProductCategoryUpdateView - редактирование категории
  • ProductCategoryDeleteView - удаление категории

7. api_views.py (78 строк)

API представления:

  • search_products_and_variants() - поиск товаров и групп вариантов для автокомплита

Преимущества новой структуры

Устранено дублирование

  • 12 функций управления фото → 4 универсальные + 12 простых оберток
  • 3 функции обработки фото → 1 универсальная функция

Улучшена организация

  • Логическое разделение по функциональным областям
  • Каждый модуль отвечает за свою сущность (Product, ProductKit, Category)
  • Легко найти нужный код

Упрощена поддержка

  • Изменения в одном типе представлений не затрагивают другие
  • Проще тестировать отдельные компоненты
  • Легче добавлять новый функционал

Обратная совместимость

  • Все импорты в urls.py работают без изменений
  • Благодаря __init__.py внешний API не изменился

Следование принципам

  • SRP (Single Responsibility Principle) - каждый модуль отвечает за одну область
  • DRY (Don't Repeat Yourself) - устранено дублирование кода
  • Separation of Concerns - разделение по ответственности

Примеры использования

Импорт представлений (работает как раньше):

from products.views import ProductListView, ProductCreateView
from products.views import productkit_photo_delete
from products.views import search_products_and_variants

Импорт из конкретного модуля (новая возможность):

from products.views.product_views import ProductListView
from products.views.photo_management import generic_photo_delete
from products.views.utils import validate_photo

Изменения в коде

Удалено:

  • Неиспользуемый импорт import json
  • Комментарий-мусор "Временный файл для добавления в views.py"

Добавлено:

  • Docstrings для всех модулей
  • Комментарии к универсальным функциям
  • Документация параметров функций

Тестирование

После рефакторинга рекомендуется:

  1. Запустить Django сервер: python manage.py runserver
  2. Проверить все CRUD операции для Product, ProductKit и Category
  3. Проверить управление фотографиями (upload, delete, set main, move up/down)
  4. Проверить API endpoint для поиска товаров

Потенциальные улучшения

В будущем можно:

  1. Добавить базовый класс BasePhotoView для дальнейшего упрощения
  2. Вынести общую логику ListView в миксины
  3. Добавить unit-тесты для каждого модуля
  4. Создать отдельный модуль для миксинов и базовых классов