Форма создания объявления в Django
У меня есть форма для создания объявления в Django, внутри которой можно добавить несколько изображений. При загрузке изображений они отображаются в предпросмотре и имеют "крестик" для того чтобы отменить их загрузку. Проблема в том что при загрузке изображений и нажатии на крестик изображение удаляется из предпросмотра. но при сохранении формы все равно остается в форме. Как сделать возможность отмены загрузки определенных изображений?
views.py:
@login_required
def additem(request):
image_form = ItemImageForm()
if request.method == 'POST':
files = request.FILES.getlist('image')
form = ItemForm(request.POST, request.FILES)
if form.is_valid():
if not files:
form.add_error(None, "Необходимо загрузить хотя бы одно изображение.")
else:
item = form.save(commit=False)
item.author = request.user
item.save()
for file in files:
ItemImage.objects.create(item=item, image=file)
return redirect('main:index')
else:
form = ItemForm()
context = {
'form': form,
'image_form': image_form,
'categories': Category.objects.all()
}
return render(
request,
template_name='main/additem.html',
context=context
)
additem.html:
<form action="{% url 'main:additem' %}" method="post" enctype="multipart/form-data" >
{% csrf_token %}
<!-- Изображение -->
<div class="file-dnd">
<label class="upload-image">Фотографии
<br><span style="color: #958f8f; font-weight:600;">Не более 10</span>
</label>
{{ image_form.image }}
{% if form.errors %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true" style="font-size: 1em;">×</span>
</button>
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
{% endif %}
{% for field in form %}
{% for error in field.errors %}
{% if field.name == 'image' and field.errors %}
Необходимо загрузить изображение.
{% endif %}
{% if error != 'Обязательное поле.' %}
{{ error }}
{% endif %}
{% endfor %}
{% endfor %}
</div>
{% endif %}
<div class="after-upload">
<div class="before-upload">
<div>
<span class="material-symbols-outlined">add_circle</span>
</div>
</div>
<div class="image-preview-container">
{% for image in item_images %}
<img src="{{ image.image.url }}" alt="Previous Image">
{% endfor %}
</div>
</div>
</div>
<div class="btn-save-wrapper">
<button type="submit" class="btn-save">Сохранить</button>
</div>
</form>
upload-image.js:
function applyDnDFile(el) {
const beforeUploadEl = el.querySelector(".before-upload");
const inputFile = el.querySelector("input[type='file']");
const imagePreviewContainer = el.querySelector(".image-preview-container");
let totalImages = 0;
function showImagePreviews(files) {
if (totalImages + files.length > 10) {
alert("Вы не можете загрузить более 10 изображений.");
return;
}
for (let i = 0; i < files.length; i++) {
const imgContainer = document.createElement("div");
imgContainer.classList.add("image-container");
const img = document.createElement("img");
const blobUrl = URL.createObjectURL(files[i]);
img.src = URL.createObjectURL(files[i]);
const deleteIcon = document.createElement("div");
deleteIcon.classList.add("delete-icon");
deleteIcon.innerHTML = "×";
imgContainer.appendChild(img);
imgContainer.appendChild(deleteIcon);
imagePreviewContainer.appendChild(imgContainer);
totalImages++;
}
}
function removeImagePreview(container) {
container.parentNode.removeChild(container);
totalImages--;
}
beforeUploadEl.addEventListener("click", (e) => {
e.preventDefault();
inputFile.click();
});
inputFile.addEventListener("change", (e) => {
e.preventDefault();
if (e.target.files.length > 10) {
alert("Вы не можете загрузить более 10 изображений.");
inputFile.value = "";
} else {
showImagePreviews(e.target.files);
}
});
imagePreviewContainer.addEventListener("click", (e) => {
if (e.target.classList.contains("delete-icon")) {
const container = e.target.parentNode;
removeImagePreview(container);
}
});
// Обработчик событий для удаления изображений
imagePreviewContainer.querySelectorAll('.delete-icon').forEach(icon => {
icon.addEventListener('click', function() {
const container = this.parentNode;
removeImagePreview(container);
});
});
}
applyDnDFile(document.querySelector(".file-dnd"));