I am attaching for reference my solution, based on many previous answers, but mostly on Raphael Eckmayer. This is how it is done to make it work well with Django 3.0.5 and dropzone.js 5.7.0. Maybe it is not the best solution, but it works.
I am sending my current images from Django view using new template tag json_script that packs my list of files prepared in Django into JSON. Basically in my template I have this:
{{ images|json_script:"images" }}
Then I process this in my script. Here is entire script from my site, hope that will help someone.
EDIT:
I had an issue with this code that if I add new pictures to the dropzone together with the old one from database I got this form submitted twice. In first pass I get pictures from dropzone.js, but also all fields since I am copying them from the form. And then, on second pass, I am submitting form again but now without pictures. My view actually was handling this well and storing data, but when I started to write down how to handle removed pictures on form edit I had issue with this, so I decided to handle this differently. Please note that code is now changed and instead of submitting form twice I am sending entire form and pictures with dropzone, but after successmultiple I am just redirecting to other page. Everything is updated and stored then. So the change is in the successmultiple part.
<script type="text/javascript">
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
Dropzone.autoDiscover = false;
var first_time = true;
var old_images = JSON.parse(document.getElementById('images').textContent)
var myDropzoneX = new Dropzone("div#mydropzone", {
autoProcessQueue: false,
url: "{% url 'site_report_edit' report_id=1 %}",
addRemoveLinks: true,
thumbnailWidth: 400,
thumbnailHeight: 400,
uploadMultiple: true,
parallelUploads: 12,
init: function() {
var myDropzone = this;
var addButton = document.getElementById("submit-btn");
if (old_images) {
console.log(old_images);
for (x in old_images) {
var mockFile = {
name: old_images[x].name,
size: old_images[x].size,
kind: 'image',
dataURL: old_images[x].urlich,
accepted: true
}
myDropzone.files.push(mockFile);
myDropzone.emit('addedfile', mockFile);
createThumbnail(mockFile);
console.log(old_images[x].name, old_images[x].urlich);
}
function createThumbnail(temp) {
myDropzone.createThumbnailFromUrl(temp,
myDropzone.options.thumbnailWidth,
myDropzone.options.thumbnailHeight,
myDropzone.options.thumbnailMethod, true, function (thumbnail) {
myDropzone.emit('thumbnail', temp, thumbnail);
myDropzone.emit("complete", temp);
});
}
myDropzone._updateMaxFilesReachedClass();
}
addButton.addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
document.getElementById("dropzone-form").submit();
}
});
this.on("successmultiple", function (files, response) {
setTimeout(function (){
{#document.getElementById("dropzone-form").submit();#}
window.location.href = "/admin/report/{{ report_id }}";
}, 1000);
});
},
sending: function (file, xhr, formData) {
var formEl = document.getElementById("dropzone-form");
if (first_time) {
for (var i=0; i<formEl.elements.length; i++){
formData.append(formEl.elements[i].name, formEl.elements[i].value)
first_time = false;
}
}
formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
formData.append("image", file.name);
}
});
</script>
Please note that there are some comments and some writing to console.log, but you can obviously get rid of this.