- Добавить несколько цветов в продукт.
- Для каждого цвета добавьте несколько размеров динамически с использованием JavaScript.
- Каждый размер должен иметь его Собственный size_name , stock и price_increment Field.
При отправке формы Django неправильно группирует значения поля с несколькими размерами в списки вместо того, чтобы рассматривать их как отдельные записи.
ожидаемый Django post Data (правильная структура) < /strong> < /h3>
Код: Выделить всё
sizes-0-0-size_name = "Small"
sizes-0-0-stock = "100"
sizes-0-0-price_increment = "50"
sizes-0-1-size_name = "Medium"
sizes-0-1-stock = "150"
sizes-0-1-price_increment = "75"
Код: Выделить всё
sizes-0-0-size_name = ["Small", "Medium"]
sizes-0-0-stock = ["100", "150"]
sizes-0-0-price_increment = ["50", "75"]
- Вместо отдельных полей для каждого размера django является значениями группировки в один список . /li>
Поле в поле размещения-0-total_forms появляется дважды в запросе POST, который может указывать на проблему дублирования JavaScript.
< /ul>
отладка данных запроса () [/b]Код: Выделить всё
request.POSTПотенциальные причины:Код: Выделить всё
- javascript Проблема: < /p>
Динамическое добавление формы может быть неправильно называть входы < /strong>, заставляя Джанго интерпретировать множественные значения как Список. < /li>для размеров может быть не обновлена должным образом, что приводит к дублирующим значениям.Код: Выделить всё
TOTAL_FORMS
django может не обнаружить входы отдельных размеров должным образом из -за неправильного префикса обработка. < /li>
< /ul>
< /li>
< /ol>
реализация кода
формы (
Код: Выделить всё
forms.pyКод: Выделить всё
class ProductForm(forms.ModelForm):
class Meta:
model = VendorProduct
fields = ['title', 'cagtegory', 'base_price']
class ProductColorForm(forms.ModelForm):
class Meta:
model = ProductColor
fields = ['color_name', 'color_code']
class ProductSizeForm(forms.ModelForm):
class Meta:
model = ProductSize
fields = ['size_name', 'stock', 'price_increment']
ProductColorFormSet = inlineformset_factory(
VendorProduct, ProductColor, form=ProductColorForm, extra=1, can_delete=True
)
ProductSizeFormSet = inlineformset_factory(
ProductColor, ProductSize, form=ProductSizeForm, extra=1, can_delete=True
)
< /code>
[b] view (views.pyКод: Выделить всё
@login_required
def add_product(request):
if request.method == 'POST':
product_form = ProductForm(request.POST)
color_formset = ProductColorFormSet(request.POST, prefix='colors')
if product_form.is_valid() and color_formset.is_valid():
product = product_form.save()
for color_index, color_form in enumerate(color_formset):
if color_form.cleaned_data.get('color_name'):
color = color_form.save(commit=False)
color.product = product
color.save()
# **Check if sizes are structured properly**
size_formset = ProductSizeFormSet(
request.POST, instance=color, prefix=f'sizes-{color_index}'
)
print(f"Processing sizes for color index {color_index}:")
print(request.POST)
if size_formset.is_valid():
size_formset.save()
return redirect('vendorpannel:vendor_shop')
else:
product_form = ProductForm()
color_formset = ProductColorFormSet(prefix='colors')
color_size_formsets = [
ProductSizeFormSet(instance=color_form.instance, prefix=f'sizes-{index}')
for index, color_form in enumerate(color_formset.forms)
]
return render(request, 'vendorpannel/add-product.html', {
'product_form': product_form,
'color_formset': color_formset,
'color_size_formsets': color_size_formsets,
})
< /code>
[b] javascript для обработки динамической формы (add_product.htmldocument.addEventListener("DOMContentLoaded", function () {
let colorIndex = document.querySelectorAll(".color-item").length;
function addColor() {
let totalForms = document.querySelector('[name="colors-TOTAL_FORMS"]');
let newColor = document.querySelector(".color-item").cloneNode(true);
newColor.querySelectorAll("input").forEach(input => {
input.name = input.name.replace(/colors-\d+/g, `colors-${colorIndex}`);
input.value = "";
});
let sizeContainer = newColor.querySelector(".sizeContainer");
sizeContainer.innerHTML = "";
let sizeTotalForms = document.createElement("input");
sizeTotalForms.type = "hidden";
sizeTotalForms.name = `sizes-${colorIndex}-TOTAL_FORMS`;
sizeTotalForms.value = "0";
sizeContainer.appendChild(sizeTotalForms);
document.getElementById("colorContainer").appendChild(newColor);
totalForms.value = colorIndex + 1;
colorIndex++;
}
document.getElementById("addColorButton")?.addEventListener("click", addColor);
});
< /code>
Что я попробовал: < /strong> < /h2>
Подробнее здесь: https://stackoverflow.com/questions/794 ... mic-fields
Мобильная версия