davidb
davidb

Reputation: 1603

Django ajax file upload form - file not uploading

I have a file upload form in html with which I'm trying to upload a file(and file size to display) via ajax call. I'm using django. Whenever I try to do anything nothing happens. Here's the upload form:

<form class="uploadForm" method="post" enctype="multipart/form-data">
  {% csrf_token %}
  <input type="file" id="uploadFile">
  <input type="submit" class="button" id="uploadButton" value="Upload">
</form>

Here's my Jquery + Ajax:

$('.uploadForm').on('submit', function(event){
  event.preventDefault();
  var fileSize = ($('#uploadFile')[0].files[0].size/1024);
  var fileName = $('#uploadFile')[0].files[0].name;
  var realSize = sizeConverter(fileSize);
  var fileData = new FormData($('#uploadFile')[0]);
  var csrfToken = '{{ csrf_token }}';
  $.ajax({
    url: '{% url 'project:uploadFile' %}',
    type: 'post',
    data: {
      'fileData': fileData,
      'fileSize': realSize,
      csrfmiddlewaretoken: '{{ csrf_token }}'
     },
    cache: false,
    processData: false,
    contentType: false,
    success: function(data){
      alert(data);
    }
  });
});

Here are views.py:

class uploadFile(TemplateView):
template_name = "project/uploadFile.html"

def post(self, request):
    fileSize = request.POST.get('fileSize')
    fileData = request.FILES['fileData']
    return JsonResponse(fileSize, safe=False)

Now, with this setup when I submit the form nothing happens. I don't get any errors in the console, nothing. When I remove 'fileData' from data and cache: false, processData: false, contentType: false, inside Ajax this works(text only though). I tried changing new FormData($('#uploadFile')[0]); to new FormData($('#uploadFile').get(0)); but that did not help. I am guessing the issue here is with the fileData variable but what could be wrong with it? I appreciate your help.

Thanks

Upvotes: 1

Views: 3153

Answers (2)

Borut
Borut

Reputation: 3364

Based on the documentation on FormData(), the correct approach would be in the sense of:

var formData = new FormData();
formData.append('fileSize', sizeConverter($('#uploadFile')[0].files[0].size/1024));
formData.append('file', $('#uploadFile')[0].files[0]);
formData.append('csrfmiddlewaretoken', '{{ csrf_token }}');
$.ajax({
    url: "{% url 'project:uploadFile' %}",
    type: 'post',
    data: formData,
    cache: false,
    processData: false,
    contentType: false,
    success: function(data){
      alert(data);
    }
});

The issue is probably here $('#uploadFile')[0]. It should be $('#uploadFile')[0].files[0]. Also, url syntax has an error with quotes.

Upvotes: 2

binpy
binpy

Reputation: 4194

I think you need to include enctype: 'multipart/form-data' in your ajax. And handle the csrfmiddlewaretoken with .append(..) method.

$('.uploadForm').on('submit', function(event){
  event.preventDefault();

  var fileSize = $('#uploadFile')[0].files[0].size/1024;
  var fileName = $('#uploadFile')[0].files[0].name;
  var realSize = sizeConverter(fileSize);

  var fileData = new FormData($('#uploadFile').get(0));
  fileData.append('csrfmiddlewaretoken', '{{ csrf_token }}');
  //fileData.append('fileData', fileData);
  fileData.append('realSize', realSize);

  $.ajax({
    url: "{% url 'project:uploadFile' %}",
    type: "POST",
    data: fileData,
    async: true,
    cache: false,
    processData: false,
    contentType: false,
    enctype: 'multipart/form-data',
    success: function(data){
      alert(data);
    }
  });
});

For generic.TemplateView you have only get method implemented. You should implement post method to allow post form or try to use generic.FormView.

Upvotes: 1

Related Questions