Django JQuery Ajax File Upload

48,697

Solution 1

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/')

Solution 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)
Share:
48,697
arnm
Author by

arnm

Updated on August 02, 2020

Comments

  • arnm
    arnm almost 4 years

    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
    arnm over 10 years
    You can use FormData, view my answer
  • Jon Snow
    Jon Snow over 10 years
    The link I gave also uses FormData, however this won't work on older browsers(caniuse.com/#search=formdata), which is why I gave the other links.
  • andilabs
    andilabs about 9 years
    could you present your form
  • whoever
    whoever over 8 years
    What's that FileUploadForm you are using?
  • arnm
    arnm over 8 years
    the form is in my original question
  • Filippo Costa
    Filippo Costa almost 7 years
    I used your code and it receives 403 because the CSRF token is missing. Any idea how to solve it?
  • Kelvin Barsana
    Kelvin Barsana over 6 years
    you can use @csrf_exempt