Для того чтобы реализовать возможность загрузки нескольких изображений одновременно с динамическим добавлением форм в админской панели, вам нужно будет немного модифицировать как форму, так и JavaScript, который отвечает за добавление и удаление форм на клиентской стороне. Ниже приведены шаги и пример кода, который поможет вам это сделать.
1. **Создайте форму для изображения**:
Вам нужно создать модель для изображений и соответствующую форму. Например, у вас может быть модель `Image`, которая связана с `Product`:
```python
from django.db import models
class Image(models.Model):
product = models.ForeignKey(Product, related_name='images', on_delete=models.CASCADE)
image = models.ImageField(upload_to='product_images/')
```
Затем создайте форму для изображения:
```python
class ImageForm(forms.ModelForm):
class Meta:
model = Image
fields = ['image']
```
2. **Измените основную форму продукта**:
Измените вашу форму `ProductForm`, чтобы использовать `InlineFormSet` для обработки нескольких изображений, но динамически добавляя их в интерфейсе:
```python
from django.forms import modelformset_factory
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = [
'name',
'category',
'price',
'stock_quantity',
'is_new',
'is_on_sale',
'colors',
'sizes',
'description',
'compositions',
]
ImageFormSet = modelformset_factory(Image, form=ImageForm, extra=1, can_delete=True)
```
3. **Создание представления**:
Теперь создайте представление, которое будет обрабатывать отправку формы и формы изображений:
```python
from django.shortcuts import render, redirect
def product_create_view(request):
if request.method == "POST":
product_form = ProductForm(request.POST)
formset = ImageFormSet(request.POST, request.FILES, queryset=Image.objects.none())
if product_form.is_valid() and formset.is_valid():
product = product_form.save()
images = formset.save(commit=False)
for image in images:
image.product = product
image.save()
return redirect('product_list') # Замените на ваш путь
else:
product_form = ProductForm()
formset = ImageFormSet(queryset=Image.objects.none())
return render(request, 'product_form.html', {
'product_form': product_form,
'formset': formset,
})
```
4. **Создание шаблона**:
В вашем шаблоне (`product_form.html`) добавьте JavaScript для динамического добавления и удаления форм:
```html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ product_form.as_p }}
<div id="image-formset">
{{ formset.management_form }}
{% for form in formset %}
<div class="form-row">
{{ form.as_p }}
<button type="button" class="remove-form">Удалить</button>
</div>
{% endfor %}
</div>
<button type="button" id="add-image">Добавить изображение</button>
<button type="submit">Сохранить</button>
</form>
<script>
document.getElementById('add-image').addEventListener('click', function() {
var formset = document.getElementById('image-formset');
var currentFormCount = formset.querySelectorAll('.form-row').length;
var newForm = document.createElement('div');
newForm.classList.add('form-row');
newForm.innerHTML =
`<div>
<input type="file" name="form-${currentFormCount}-image" required>
<button type="button" class="remove-form">Удалить</button>
</div>`;
formset.appendChild(newForm);
// Обновляем количество форм в management_form
var totalForms = document.getElementById('id_form-TOTAL_FORMS');
totalForms.value = currentFormCount + 1;
});
document.getElementById('image-formset').addEventListener('click', function(e) {
if (e.target.classList.contains('remove-form')) {
e.target.closest('.form-row').remove();
}
});
</script>
```
5. **Изменение стилей или логики**:
Вы можете настроить CSS для улучшения внешнего вида и взаимодействия с формами.
Э