Enforce parameter binding requirement for ConfigurableKitProduct variants
Changes: 1. Removed unused attributesMetadata container from configurablekit_form.html - Dead code from old formset-based attribute system - 10 lines of unused HTML and templating removed 2. Enhanced formset validation in BaseConfigurableKitOptionFormSet.clean(): - If product HAS parameters: variants MUST select values for ALL parameters - If product HAS NO parameters: variants MUST NOT be created - Error message guides user to add parameters first Business logic: - ConfigurableKitProduct variants (options) are ALWAYS bound to attribute values - You cannot create orphan variants without parameter selections - Each variant must have a value for every product parameter User experience: - Clear error message if trying to add variant without parameters - Enforces proper product structure: parameters first, then variants 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -722,7 +722,7 @@ class BaseConfigurableKitOptionFormSet(forms.BaseInlineFormSet):
|
||||
parent = self.instance
|
||||
if parent and parent.pk:
|
||||
# Получаем все уникальные названия атрибутов родителя
|
||||
attribute_names = (
|
||||
attribute_names = list(
|
||||
parent.parent_attributes
|
||||
.all()
|
||||
.order_by('position', 'name')
|
||||
@@ -730,17 +730,24 @@ class BaseConfigurableKitOptionFormSet(forms.BaseInlineFormSet):
|
||||
.values_list('name', flat=True)
|
||||
)
|
||||
|
||||
# Проверяем что каждый атрибут выбран
|
||||
missing_attributes = []
|
||||
for attr_name in attribute_names:
|
||||
field_name = f'attribute_{attr_name}'
|
||||
if field_name not in form.cleaned_data or not form.cleaned_data[field_name]:
|
||||
missing_attributes.append(attr_name)
|
||||
# Если у товара есть параметры, вариант ОБЯЗАН иметь значения для них
|
||||
if attribute_names:
|
||||
# Проверяем что каждый атрибут выбран
|
||||
missing_attributes = []
|
||||
for attr_name in attribute_names:
|
||||
field_name = f'attribute_{attr_name}'
|
||||
if field_name not in form.cleaned_data or not form.cleaned_data[field_name]:
|
||||
missing_attributes.append(attr_name)
|
||||
|
||||
if missing_attributes:
|
||||
attrs_str = ', '.join(f'"{attr}"' for attr in missing_attributes)
|
||||
if missing_attributes:
|
||||
attrs_str = ', '.join(f'"{attr}"' for attr in missing_attributes)
|
||||
raise forms.ValidationError(
|
||||
f'Вариант {idx + 1}: необходимо заполнить атрибут(ы) {attrs_str}.'
|
||||
)
|
||||
else:
|
||||
# Если у товара нет параметров, вариант без привязки к параметрам бессмысленен
|
||||
raise forms.ValidationError(
|
||||
f'Вариант {idx + 1}: необходимо заполнить атрибут(ы) {attrs_str}.'
|
||||
f'Вариант {idx + 1}: сначала добавьте параметры товара в разделе "Параметры товара".'
|
||||
)
|
||||
|
||||
# Проверяем, что не более одного "is_default"
|
||||
|
||||
@@ -258,17 +258,6 @@ input[name*="DELETE"] {
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- Скрытый контейнер с информацией об атрибутах для JavaScript -->
|
||||
<div id="attributesMetadata" style="display: none;">
|
||||
{% for attr in attribute_formset %}
|
||||
{% if attr.cleaned_data or attr.instance.pk %}
|
||||
<div data-attr-name="{{ attr.cleaned_data.name|default:attr.instance.name }}"
|
||||
data-attr-id="{{ attr.instance.id }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" id="addOptionBtn">
|
||||
<i class="bi bi-plus-circle me-1"></i>Добавить вариант
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user