Files
octopus/myproject/test_configurable_simple.py
Andrey Smakotin def795f0ad Implement card-based interface for ConfigurableKitProduct attributes
This commit introduces a new user-friendly interface for managing product attributes:

1. **Form Changes** (products/forms.py):
   - Removed 'option' field from ConfigurableKitOptionForm (values now inline)
   - Updated ConfigurableKitProductAttributeFormSetCreate to only include name, position, visible
   - Updated BaseConfigurableKitProductAttributeFormSet validation for new structure

2. **Template Updates** (products/templates/products/configurablekit_form.html):
   - Replaced row-based attribute interface with card-based design
   - Each card contains:
     - Parameter name field
     - Position field
     - Visibility toggle
     - Inline value inputs with add/remove buttons
   - "Add parameter" button creates new cards
   - "Add value" button adds inline value inputs

3. **JavaScript Enhancements**:
   - addValueField(): Creates new value input with delete button
   - initAddValueBtn(): Initializes add value button for each card
   - addParameterBtn: Dynamically generates new parameter cards
   - serializeAttributeValues(): Converts inline values to JSON for POST submission
   - Form submission intercept to serialize data before sending

4. **View Updates** (products/views/configurablekit_views.py):
   - Both Create and Update views now have _save_attributes_from_cards() method
   - Reads attributes-X-values JSON from POST data
   - Creates ConfigurableKitProductAttribute for each parameter+value combination
   - Handles parameter deletion and visibility toggling

**Key Features**:
✓ One-time parameter name entry with multiple inline values
✓ Add/remove values without reloading page
✓ Add/remove entire parameters with one click
✓ No database changes required
✓ Better UX: card layout more intuitive than rows
✓ Proper JSON serialization for value transmission

🤖 Generated with Claude Code

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

132 lines
4.5 KiB
Python

#!/usr/bin/env python
"""
Prostoy test skript dlya proverki ConfigurableKitOptionAttribute
bez Unicode simvolov
"""
import os
import sys
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()
from products.models.kits import (
ConfigurableKitProduct,
ConfigurableKitOption,
ConfigurableKitProductAttribute,
ConfigurableKitOptionAttribute,
ProductKit
)
from django_tenants.utils import tenant_context
from tenants.models import Client
try:
client = Client.objects.get(schema_name='grach')
print(f"OK: Found tenant: {client.name} (schema: {client.schema_name})\n")
except Client.DoesNotExist:
print("ERROR: Tenant 'grach' not found")
print("Available tenants:")
for c in Client.objects.all():
print(f" - {c.name} ({c.schema_name})")
sys.exit(1)
with tenant_context(client):
print("=" * 70)
print("TEST: ConfigurableKitOptionAttribute M2M Model")
print("=" * 70)
# Test 1: Check models exist
print("\n1. Checking if models exist...")
try:
# Try to get a ConfigurableKitProduct
products = ConfigurableKitProduct.objects.filter(name__icontains="test").first()
if products:
print(f" OK: Found ConfigurableKitProduct: {products.name}")
else:
print(" INFO: No test ConfigurableKitProduct found")
# Check ConfigurableKitProductAttribute exists
attrs = ConfigurableKitProductAttribute.objects.all()
print(f" OK: ConfigurableKitProductAttribute model exists. Count: {attrs.count()}")
# Check ConfigurableKitOptionAttribute exists
opt_attrs = ConfigurableKitOptionAttribute.objects.all()
print(f" OK: ConfigurableKitOptionAttribute model exists. Count: {opt_attrs.count()}")
except Exception as e:
print(f" ERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
# Test 2: Check M2M relationships
print("\n2. Checking M2M relationships...")
try:
# Get a sample variant
option = ConfigurableKitOption.objects.first()
if option:
print(f" OK: Found option: {option.id} for parent: {option.parent.name}")
# Check if we can access attributes_set
attr_set = option.attributes_set.all()
print(f" OK: Can access attributes_set. Count: {attr_set.count()}")
# Check if we can reverse access
if attr_set.exists():
opt_attr = attr_set.first()
print(f" OK: Can access option_attr.option: {opt_attr.option.id}")
print(f" OK: Can access option_attr.attribute: {opt_attr.attribute.id}")
else:
print(" INFO: No ConfigurableKitOption found")
except Exception as e:
print(f" ERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
# Test 3: Check form validation logic
print("\n3. Checking form validation setup...")
try:
from products.forms import ConfigurableKitOptionForm
# Create a test form with instance
option = ConfigurableKitOption.objects.filter(
parent__parent_attributes__isnull=False
).first()
if option:
form = ConfigurableKitOptionForm(instance=option)
print(f" OK: Form created for option with parent: {option.parent.name}")
# Check dynamically generated fields
dynamic_fields = [f for f in form.fields if f.startswith('attribute_')]
print(f" OK: Found {len(dynamic_fields)} dynamic attribute fields:")
for field_name in dynamic_fields:
print(f" - {field_name}")
else:
print(" INFO: No option with parent attributes found")
except Exception as e:
print(f" ERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
# Test 4: Check view integration
print("\n4. Checking view imports...")
try:
from products.views.configurablekit_views import (
ConfigurableKitProductCreateView,
ConfigurableKitProductUpdateView
)
print(" OK: Views imported successfully")
print(" OK: ConfigurableKitProductCreateView available")
print(" OK: ConfigurableKitProductUpdateView available")
except Exception as e:
print(f" ERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
print("\n" + "=" * 70)
print("OK: ALL TESTS PASSED! Implementation is ready for testing.")
print("=" * 70)