30

I've been trying to upload a simple text file for hours now but I still can't seem to get it working.

I keep getting invalid forms saying I'm missing the "file_source".

Why is "file_source" not getting posted?

I've also got it to actually send "file_source" but it still says it is missing. What type of element should be given to a Django FileFiled?

Django Form:

class FileUploadForm(forms.Form):
    file_source = forms.FileField()

Django Template (renders form):

<form action="/upload/" method="post" id="file-upload-form" enctype="multipart/form-data"> {% csrf_token %}
    {{ form }}
    <button type="submit" class="btn btn-primary" id='upload-btn'>Upload</button>
</form>

JQuery/Ajax Upload:

function uploadFile() {
$.ajax({
    data: $(this).serialize(),
    type: $(this).attr('method'),
    url: $(this).attr('action')
});
return false;
}

$(function() {
     $('#file-upload-form').submit(uploadFile);
});

Django View Which recieves POST:

def upload_view(request):
if request.is_ajax():
    form = FileUploadForm(request.POST)
    if form.is_valid():
        print 'valid form'
    else:
        print 'invalid form'
        print form.errors
return HttpResponseRedirect('/ingest/')
arnm
  • 1,705
  • 2
  • 19
  • 30
  • 2
    You have to use FormData or flash or Iframes to send files, I recommend the use of FormData see this answer http://stackoverflow.com/questions/20715606/post-data-using-ajax-post/20715760#20715760 – Victor Castillo Torres Dec 29 '13 at 07:02
  • possible duplicate of [How can I upload files asynchronously with jQuery?](http://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously-with-jquery) – Nicolas Cortot Dec 29 '13 at 08:16
  • @Nicolas It is similar but not the same. I needed a way to get Django to correctly interpret the ajax post. – arnm Dec 30 '13 at 23:03

3 Answers3

56

Here is what I changed to get it working.

  1. I used FormData to package up data from form

  2. Notice the parameters of the form in the Django view. I was not specifying "files" before and that's what caused the " file field required" error.

Javascript:

function upload(event) {
event.preventDefault();
var data = new FormData($('form').get(0));

$.ajax({
    url: $(this).attr('action'),
    type: $(this).attr('method'),
    data: data,
    cache: false,
    processData: false,
    contentType: false,
    success: function(data) {
        alert('success');
    }
});
return false;
}

$(function() {
    $('form').submit(upload);
});

Django View:

def upload_view(request):
    if request.method == 'POST':
        form = FileUploadForm(data=request.POST, files=request.FILES)
        if form.is_valid():
            print 'valid form'
        else:
            print 'invalid form'
            print form.errors
    return HttpResponseRedirect('/ingest/')
arnm
  • 1,705
  • 2
  • 19
  • 30
2

Here's how we can send json data in addition to files using Ajax to Django.

Example:

JS using form-data

var formData = new FormData();
formData.append('file1', myFile); 
const data_ = JSON.stringify(data)
formData.append('data', data_);

doPost(url, formData)
.then(result => {
 })

Django using request.FILES & request.POST

data = json.loads(request.POST.get('data'))
 files = request.FILES
 attached_file1 = files.get('file1', None)
 attr1 = data.get('attr1', None)
Abdallah Okasha
  • 1,879
  • 17
  • 20
-2

You can't use jQuery to upload files asynchronously. You options are:

1.Submit the form "the usual way". This, of course, will refresh the page.

2.Use XHR: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest but beware that it's not supported on IE 8/9 . On those browsers you would need to fall back to an iframe and a form that posts to it, to mimic an asynchronous upload.

3.Use https://github.com/blueimp/jQuery-File-Upload It does what I described in 2. but spares you all the configuring.

Jon Snow
  • 3,682
  • 4
  • 30
  • 51
  • 4
    You can use FormData, view my answer – arnm Dec 30 '13 at 23:01
  • The link I gave also uses FormData, however this won't work on older browsers(http://caniuse.com/#search=formdata), which is why I gave the other links. – Jon Snow Dec 31 '13 at 10:19