Search code examples
ajaxdjangodjango-file-uploaddjango-excel

Make django ajax view return a file


I'm having trouble when trying to return a file through a view.

Working case: User submits a form, I instanciate an excel file from these values and return it to the user. After submitting, user got a popup inviting him to download the file. No problem.

Not working case: User selects values from a jstree and submits them with ajax. Again I instanciate an excel file and return it. However, though everything goes fines (no server error, success function triggered in ajax), nothing happens. The file is created this way:

    response = HttpResponse(content_type='application/ms-excel')
    response['Content-Disposition'] = 'attachment; filename="export.xls"'
    response = comparaison(response, wb, ws_same, ws_diff, tree_left, tree_right)
    wb.save(response)
    return response

It goes fine in first case but not in second.

I've also tried to find a workaround by saving the file on the server for a short time and redirect user to its location in this way.

wb.save('export.xls')
return redirect(path_to_export_xls)

It also gives no error but triggers nothing. I've no idea of what I'm missing, the only difference I see is that in the second case, file is not generated from syncronous post submit but I cant why it should be an issue.

Thanks in advance for any suggestion.

PS : here is ajax code.

`$('#button_compare').on('click', function () {
    var raw_left = jstreeDiv.jstree(true).get_checked(true),
        raw_right = jstreeCreate.jstree(true).get_checked(true),
        tree_left = [],
        tree_right = [];
    for(var i = 0; i<raw_left.length ; i++){
        tree_left.push(raw_left[i].li_attr['data-id']);
    }
    for(var i = 0; i<raw_right.length; i++){
        tree_right.push(raw_right[i].li_attr['data-id']);
    }
    $.ajax({
        url: '../Comparer/',
        type: 'POST',
        beforeSend: function (xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        },
        data: {
            'tree_left': JSON.stringify(tree_left),
            'tree_right': JSON.stringify(tree_right)
        },
        /*
        success:function(response){
            alert('OK');
        },
        error:function (xhr, status, error) {
            return false ;
        }
        */
    });
});

`


Solution

  • According to @Daniel Roseman's answer, submitting data through ajax prevent using Django views default return for file. In the end I stored the file in a temp folder on server side and display a popup (with jQueryUI) with a link to the file and delete the file after user download.