feat(products): обеспечить уникальность единицы продажи по умолчанию и улучшить UI формы
Добавлено ограничение на уровне базы данных и валидация форм для обеспечения, что у товара может быть только одна единица продажи с флагом "по умолчанию". Переработан интерфейс маркетинговых флагов и единиц продажи для улучшения UX. Основные изменения: - Добавлен UniqueConstraint в модель ProductSalesUnit для валидации на уровне БД - Создан BaseProductSalesUnitFormSet с кастомной валидацией формы - Обновлен метод save() для корректной обработки новых и существующих записей - Добавлена транзакционная обертка в представлениях ProductCreateView и ProductUpdateView - Переработан блок маркетинговых флагов с карточным дизайном и интерактивными переключателями - Переработан блок единиц продажи в табличный вид с улучшенным UX - Добавлена клиентская логика для взаимного исключения чекбоксов "По умолчанию
This commit is contained in:
@@ -1321,12 +1321,49 @@ class ProductSalesUnitInlineForm(forms.ModelForm):
|
||||
return super().has_changed()
|
||||
|
||||
|
||||
class BaseProductSalesUnitFormSet(forms.BaseInlineFormSet):
|
||||
"""
|
||||
Базовый формсет для единиц продажи с валидацией.
|
||||
Обеспечивает, что только одна единица продажи может быть по умолчанию.
|
||||
"""
|
||||
def clean(self):
|
||||
if any(self.errors):
|
||||
return
|
||||
|
||||
default_count = 0
|
||||
default_forms = []
|
||||
|
||||
for form in self.forms:
|
||||
if self.can_delete and self._should_delete_form(form):
|
||||
continue
|
||||
|
||||
if not form.cleaned_data:
|
||||
continue
|
||||
|
||||
if form.cleaned_data.get('is_default'):
|
||||
default_count += 1
|
||||
default_forms.append(form)
|
||||
|
||||
if default_count > 1:
|
||||
# Находим названия единиц с is_default для более информативного сообщения
|
||||
unit_names = []
|
||||
for form in default_forms:
|
||||
name = form.cleaned_data.get('name', 'Без названия')
|
||||
unit_names.append(f'"{name}"')
|
||||
|
||||
raise forms.ValidationError(
|
||||
f'Можно установить только одну единицу продажи как "по умолчанию". '
|
||||
f'Найдено {default_count} единиц с флагом "по умолчанию": {", ".join(unit_names)}.'
|
||||
)
|
||||
|
||||
|
||||
# Inline formset для единиц продажи
|
||||
ProductSalesUnitFormSet = inlineformset_factory(
|
||||
Product,
|
||||
ProductSalesUnit,
|
||||
form=ProductSalesUnitInlineForm,
|
||||
extra=1,
|
||||
formset=BaseProductSalesUnitFormSet,
|
||||
extra=0,
|
||||
can_delete=True,
|
||||
min_num=0,
|
||||
validate_min=False,
|
||||
|
||||
Reference in New Issue
Block a user