I'd like to implement a multifile upload feature into a site. There is already an upload feature on the site, but for single files. I'm following loosely the Simple Is Better Than Complex: Django Multiple Files Upload Using Ajax.
My code:
views->mulit_upload.py
class BasicUploadView(View):
def get(self, request):
files_list = Multi_File.objects.all()
#files_list = ['testing_123']
print ("files_list: {0}".format(files_list))
return render(self.request, 'myproject/multi_upload.html', {'filesList': files_list})
def post(self, request):
form = FileForm(self.request.POST, self.request.FILES)
if form.is_valid():
multiFile = form.save()
data = {'is_valid': True, 'name': multiFile.file.name, 'url': multiFile.file.url}
else:
data = {'is_valid': False}
return JsonResponse(data)
models.py
class Multi_File(models.Model):
title = models.CharField(max_length=255, blank=True)
file = models.FileField(upload_to='files/')
uploaded_at = models.DateTimeField(auto_now_add=True)
forms.py
class FileForm(forms.ModelForm):
class Meta:
model = Multi_File
fields = ('file', )
multi_upload.html
{% load static %}
{% block javascript %}
<script src="{% static 'myproject/js/jQuery-File-Upload-9.14.1/js/vendor/jquery.ui.widget.js' %}"></script>
<script src="{% static 'myproject/js/jQuery-File-Upload-9.14.1/js/jquery.iframe-transport.js' %}"></script>
<script src="{% static 'myproject/js/jQuery-File-Upload-9.14.1/js/jquery.fileupload.js' %}"></script>
<script src="{% static 'myproject/upload-files.js' %}"></script>
{% endblock %}
{# 1. BUTTON TO TRIGGER THE ACTION #}
<div class="col-md-4">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile" multiple>
<button type="submit">Upload<span class="glyphicon glyphicon-cloud-upload"></span> </button>
</form>
</div>
{# 2. FILE INPUT TO BE USED BY THE PLUG-IN #}
<input id="fileupload" type="file" name="myfile" multiple
style="display: none;"
data-url="{% url 'myproject:multi_import' %}"
data-form-data='{"csrfmiddlewaretoken": "{{ csrf_token }}"}'>
{# 3. TABLE TO DISPLAY THE UPLOADED PHOTOS #}
<table id="gallery" class="table table-bordered">
<thead>
<tr>
<th>Uploaded Files:</th>
</tr>
</thead>
<tbody>
{% for aFile in filesList %}
<tr>
<td><a href="{{ aFile.file.url }}">{{ aFile.file.name }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
upload_files.js
$(function () {
/* 1. OPEN THE FILE EXPLORER WINDOW */
$(".js-upload-files").click(function () {
$("#fileupload").click();
});
/* 2. INITIALIZE THE FILE UPLOAD COMPONENT */
$("#fileupload").fileupload({
dataType: 'json',
done: function (e, data) { /* 3. PROCESS THE RESPONSE FROM THE SERVER */
if (data.result.is_valid) {
$("#gallery tbody").prepend(
"<tr><td><a href='" + data.result.url + "'>" + data.result.name + "</a></td></tr>"
)
}
}
});
});
Problems so far: 1. Upload doesn't work when clicking on the button. The box appears, I can select numerous files and "upload" to the page i.e. it says 2 files selected. But then clicking "Upload" gives the error:
{"is_valid": false}
This comes from the view (mulit_uploade.py
) but I'm a bit confused why
I'd like to use the
base.html
that was also used for the single upload feature. So when I add{% extends "myproject/base.html" %}
to themulti_upload.html
, a new problem appears that doesn't appear when I just use the single upload feature:Reverse for 'myproject_about' not found. 'myproject_about' is not a valid view function or pattern name:
Learn more »
NoReverseMatch at /myproject/import/
Reverse for 'myproject_about' not found. 'myproject_about' is not a valid view function or pattern name
To start off you will need a formset(https://docs.djangoproject.com/en/2.1/topics/forms/formsets/), to be able to upload multiple files at once. So the code will roughly look like this
Now each file will have some unique id, as you will see when you use formset. to populate data in the table, you need to listen for file change event and change the table.