4

I want to post a form in django using jquery. I want my form to be able to post a file too. Using form.serialize() as I have read wont pass the contents of the file field. So I read about FormData. But when I use FormData my django view won't recognize it as ajax request. My code (using serialize)

$.ajax({
    url:'/customer/create/',
    type: form.attr('method'),
    contentType:'application/x-www-form-urlencoded;charset=utf-8',                    
    dataType:'json',
    data:form.serialize(),
    success:onSuccess,
    error: function(xhr, ajaxOptions, thrownError){
        alert(thrownError + '\n' + xhr.status + '\n' + ajaxOptions);
    }
});

and with form data

fd = new FormData(form)
$.ajax({
    url:'/customer/create/',
    type: form.attr('method'),
    contentType:'multipart/form-data',                    
    dataType:'json',
    data:fd,
    success:onSuccess,
    error: function(xhr, ajaxOptions, thrownError){
        alert(thrownError + '\n' + xhr.status + '\n' + ajaxOptions);
    }
});

Am I missing somethig here? I am not sure this must be the correct contentType. Also mutipart/form-data is set in enctype attribute of the form.

Also I know about jquery-forms, but don't want to use it yet. I only want this to happen at one form of mine so I don't want to load it in my page. I want to see if there is a solution before going there.

Apostolos
  • 7,763
  • 17
  • 80
  • 150
  • Files cannot be uploaded via AJAX unless you use some jQuery plugins.like https://github.com/sigurdga/django-jquery-file-upload – Yogesh dwivedi Geitpl Jan 27 '14 at 10:52
  • 5
    Files can indeed be uploaded using FormData and without plugins as explained here - http://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery I am not sure what you mean by Django not recognizing the ajax request. If you are getting a HTTP 403, it could be because you might not have included csrf_token in your form. – shaktimaan Jan 30 '14 at 00:43
  • @warunsl That's what i followed, only request.is_ajax() return false in django view – Apostolos Jan 30 '14 at 08:44
  • 1
    try `contentType: false` and add `enctype="multipart/form-data"` to your
    tag. Do note FormData doesnt work on IE (at least I've tried IE9 and 8). And serialize does work with multipart. Try malsup plugin: https://github.com/malsup/form/
    – George Apr 25 '14 at 07:00
  • @RajeshP http://www.needsmorejquery.com/ – John Weisz Apr 23 '15 at 09:27

2 Answers2

4

I needed to do something like this:

$('#cover_url_file_input').on('change', function(e) {

      var file, imgData;
      file = this.files[0];

      if (file) {

        imgData = new FormData();
        imgData.append('cover_url', file);

        $.ajax({
          type: 'POST',
          url: $('#cover-form').attr('action'),
          data: imgData,
          processData: false,
          contentType: false,
          cache: false,

          success: function(result) {
            if (result.info === 'OK') {
              console.log('OK');
            }
          }

        });

      }
});
andilabs
  • 22,159
  • 14
  • 114
  • 151
3

When using FormData, you need to add processData: false to your jQuery.ajax options so jQuery won't try processing something it cannot. So do this, and you should be fine:

var form = $('#theForm'),
    fd = new FormData(form[0]);

$.ajax({
    url: '/customer/create/',
    type: form.attr('method'),
    contentType: 'multipart/form-data',                    
    dataType: 'json',
    data: fd,
    processData: false,
    success: onSuccess,
    error: function(xhr, ajaxOptions, thrownError){
        alert(thrownError + '\n' + xhr.status + '\n' + ajaxOptions);
    }
});
Fardin K.
  • 445
  • 9
  • 19
  • 1
    @andi sorry to hear that. I'm not sure about the Django side, but this very setup is being used in a couple of live projects right now. However, there is one error that I see in my snippet now; if `form` is a jQuery object, you should change the first line to `fd = new FormData(form.get(0))` – Fardin K. Mar 28 '15 at 08:03