1

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

2
  • csrfmiddlewaretoken in your javascript, try to change 'csrfmiddlewaretoken' Commented Dec 8, 2017 at 21:41
  • When I do this I get "Forbidden (CSRF token missing or incorrect.)" Commented Dec 8, 2017 at 21:48

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Now I'm getting "Method not allowed(POST)". Is it not going to the correct place or something?
I don't know. Give me a minute to test. What's your url in urls?
url(r'bienbox/bucket/uploadFile/$',views.uploadFile.as_view(),name='uploadFile'),. Thank you for your help.
I have tested this code and copy/pasted your view and it works. You're probably getting Method not allowed because some other url is consuming your uploadFile url.
Btw, now when I submit the form it redirects to the same page. Shouldn't preventDefault() work?
|
1

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.

5 Comments

Now I'm getting "Method not allowed(POST)". Is it not going to the correct place or something?
how about adding http_method_names = ['get', 'post'] in your view, see this ccbv.co.uk/projects/Django/1.11/django.views.generic.base/…
Tested now, still the same. Cheers for your help. I will try to get this working somehow.
Please check my original post. There I copied my views.py with post method included. As I mentioned, I can post the form with text only('fileSize'). I can't post the file still.
great answer - after hours of debugging

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.