Динамическое добавление/удаление набора форм Django Не работает для цветов, размеров и изображений
Постановка задачи
Я работаю над набором форм Django, где пользователи могут динамически добавлять/ удалять цвета, размеры и изображения при добавлении товара.
Структура моего набора форм выглядит следующим образом:
- Продукт может иметь несколько цветов.
- Каждый цвет может иметь несколько размеров.
- Каждый цвет может содержать несколько изображений.
- Пользователи должны иметь возможность динамически добавлять/удалять цвета, размеры и изображения с помощью JavaScript.
Ожидаемое поведение
- При нажатии кнопки
"Add Color"
должна быть создана новая цветовая форма со своим собственным размером и разделами изображений. - Нажатие
"Add Size"
в пределах цвета должно добавить новый размер только к этому конкретному цвету. - Нажатие
"Add Image"
в пределах цвета должно добавить новое изображение только к этому конкретному цвету. - Нажатие кнопки
"Remove Color"
должно удалить раздел с определенным цветом.
Текущая проблема
- Работает только кнопка "Удалить цвет".
"Add Color"
,"Add Size"
, и кнопки"Add Image"
не работают.- При нажатии кнопок к DOM не добавляются новые элементы.
Попытки отладки
✔ Проверил Формы управления набором форм Django (они существуют).
✔ Проверенные прослушиватели событий подключаются с помощью console.log()
.
✔ Гарантируется, что cloneNode(true)
правильно копирует элементы.
✔ Проверено на наличие ошибок JavaScript в консоли (синтаксических ошибок нет).
Формы и наборы форм Django
Формы (forms.py)
from django import forms
from django.forms import inlineformset_factory
from .models import VendorProduct, ProductColor, ProductSize, ProductImage, ColorImage
class ProductForm(forms.ModelForm):
class Meta:
model = VendorProduct
fields = ['title', 'category', 'base_price']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'category': forms.Select(attrs={'class': 'form-control'}),
'base_price': forms.NumberInput(attrs={'class': 'form-control'}),
}
class ProductColorForm(forms.ModelForm):
class Meta:
model = ProductColor
fields = ['color_name', 'color_code']
widgets = {
'color_name': forms.TextInput(attrs={'class': 'form-control'}),
'color_code': forms.TextInput(attrs={'class': 'form-control'}),
}
class ProductSizeForm(forms.ModelForm):
class Meta:
model = ProductSize
fields = ['size_name', 'stock', 'price_increment']
widgets = {
'size_name': forms.TextInput(attrs={'class': 'form-control'}),
'stock': forms.NumberInput(attrs={'class': 'form-control'}),
'price_increment': forms.NumberInput(attrs={'class': 'form-control'}),
}
class ProductImageForm(forms.ModelForm):
class Meta:
model = ProductImage
fields = ['image']
widgets = {
'image': forms.FileInput(attrs={'class': 'form-control'}),
}
class ColorImageForm(forms.ModelForm):
class Meta:
model = ColorImage
fields = ['image']
widgets = {
'image': forms.FileInput(attrs={'class': 'form-control'}),
}
# Formsets
ProductColorFormSet = inlineformset_factory(VendorProduct, ProductColor, form=ProductColorForm, extra=1, can_delete=True)
ProductImageFormSet = inlineformset_factory(VendorProduct, ProductImage, form=ProductImageForm, extra=1, can_delete=True)
ProductSizeFormSet = inlineformset_factory(ProductColor, ProductSize, form=ProductSizeForm, extra=1, can_delete=True)
ColorImageFormSet = inlineformset_factory(ProductColor, ColorImage, form=ColorImageForm, extra=1, can_delete=True)
<время работы/>
HTML-шаблон (add_product.html)
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div id="colorContainer">
{% for color_form in color_formset %}
<div class="color-item">
{{ color_form.color_name.label_tag }}
{{ color_form.color_name }}
{{ color_form.color_code.label_tag }}
{{ color_form.color_code }}
<!-- Image Uploads -->
<label>Color Images</label>
{{ color_image_formset.management_form }}
{% for image_form in color_image_formset %}
<div class="image-item">
{{ image_form.image }}
</div>
{% endfor %}
<button type="button" class="add-image-btn">Add Image</button>
<!-- Size Section -->
<div class="sizeContainer">
<h4>Sizes</h4>
{{ size_formset.management_form }}
{% for size_form in size_formset %}
<div class="size-item">
{{ size_form.size_name.label_tag }}
{{ size_form.size_name }}
{{ size_form.stock.label_tag }}
{{ size_form.stock }}
{{ size_form.price_increment.label_tag }}
{{ size_form.price_increment }}
</div>
{% endfor %}
</div>
<button type="button" class="add-size-btn">Add Size</button>
<button type="button" class="remove-btn">Remove Color</button>
</div>
{% endfor %}
</div>
<button type="button" id="addColorButton">Add Color</button>
<button type="submit">Save</button>
</form>
<время работы/>
JavaScript (dynamic.js)
<время работы/>Краткое изложение проблем
- Прослушиватели событий не были подключены должным образом.
- Имена наборов форм динамически не обновлялись.
- JavaScript неправильно использовал делегирование событий.
- Скрипт должен был обрабатывать как статические, так и динамически добавляемые элементы.