I am working on a project where the functionality is the user can upload his multiple images with a drag-n-drop feature. I am developing using the Django-python. I have impl
Small upgrade on previous post overriding submit, I would like to add options:selected
looping.
$('option:selected').each(function(){
var name = $(this).parent().attr('name')
if ($(this).val()) {
var val = $(this).val()
console.log('name: ' + name + ' value: ' + val);
formData.append(name, val);
}
else {
var val = ""
console.log('name: ' + name + ' value: ' + val);
formData.append(name, val);
}
});
I am glad that you have solved it. I have spent a few hours on this this is how I solved it:
The main issue with using dropzone is that as soon as files being droped in it, it will start to upload. So the images will not upload along with the rest of the form data.
To deal with this, I had to create the dropzone object programmatically with the following settings:
$(document).ready(function(){
var list_of_files = new Array();
Dropzone.autoDiscover = false; //prevent dropzone to automatically discover the dropzone object in your html
$("div#dropzone").dropzone({
uploadMultiple: true, // allow multiple upload
autoProcessQueue: false, // prevent dropzone from uploading automatically
url: "/", //dropzone needs a url attribute or it complains, what value you put here does not really matter. It is only purpose is to prevent a javascript error message from chrome console
maxFiles: 5, //set max uploads to 5 since you only have 5 image files in your model
init: function(){
//everytime a file is uploaded, save the file object
//for later use
this.on("addedfile", function(file)
{
if (list_of_files.length < 5)
{
list_of_files.push(file)
console.log("file added");
}
});
}
});
// the following function override the "submit" button in the form
$(document).on("click", "button", function(e){
e.preventDefault() //prevent the form from submitting
console.log('num of files: ' + list_of_files.length);
var formData = new FormData(); // construct our own upload data
var inputs = $("#newUserForm input");
//get all of the data from textboxes
$.each(inputs, function(obj, v){
var name = $(v).attr("name")
var val = $(v).val();
console.log('name: ' + name + ' value: ' + val);
formData.append(name, val);
});
//get the file object from dropzone and put it into our formdata
for(i=0;i<list_of_files.length;i++)
{
formData.append('user_image'+(i+1), list_of_files[i]);
}
var request = new XMLHttpRequest();
request.open("POST", "/"); //config your post url here
request.send(formData); //send the post request to server
});
});
Here is the template file:
<form id="newUserForm" name="newUserForm" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% if form %}
{% for field in form %}
<p>{{ field.label_tag }} {{ field }}</p>
{% endfor %}
{% endif %}
<!-- The div for uploading the images -->
<div id="dropzone" class="dropzone"></div>
<button id='save'> save </button>
</form>
I also added exclude to forms.py (so that these fields will not show up in our template, we have dropzone to replace them):
class CustomerInfoForm(forms.ModelForm):
class Meta:
model = CustomerProfile
exclude=('user_image1','user_image2','user_image3','user_image4','user_image5')
All of the code above does is to submit the data from each text box with the images to your views.py together in one step
Here is the views.py:
def index(request):
if request.method == 'POST':
form = CustomerInfoForm(request.POST)
if (form.is_valid()):
instance = form.save(commit=False)
#request.FILES contains all of the uploaded images
#key is 'user_image1', 'user_image2', value is the image file in memory
for key, value in request.FILES.iteritems():
a_path = '/a/b'
save_uploadfile_to_disk(a_path, file)
setattr(instance, key, a_path) //I made up the path here
form.save() //save the form for real
#do not forget to return a response
else:
print form.errors #for debugging only
else:
form = CustomerInfoForm()
context = {'form': form}
return render(request, 'test_dropzone/index.html', context)
def save_uploadfile_to_disk(full_path, file):
with open(full_path, 'w+') as destination:
for chunk in file.chunks():
destination.write(chunk)
I tested this solution using Django 1.8 and it works. I checked the database and the path has been written to the record correctly.
Now, to reflect upon this solution, it kind of defeated the purpose of using dropzone. Because users cannot upload the photos as soon as a file has been selected.
Since you have also solved this problem. Please post your solution and I am looking forward to learn something new from yours :)