Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generating a file with django to download with javascript/jQuery

Using Django, I want to make some data available for download.

My jQuery call looks like this so far:

$.getJSON("/get_data", 
            { users: users, study: "{{study.id}}" } ,
            function(json){
                alert('some data!');
            }
);

This calls one of my Django views, which in turn generates some JSON and attempts to make that JSON text in a file to download

jsonResponse = json.dumps(data, cls=DjangoJSONEncoder)

jsonFile = cStringIO.StringIO()
jsonFile.write(jsonResponse)

response = HttpResponse(jsonFile, mimetype='application/json')
response['Content-Disposition'] = 'attachment; filename=data.txt'

return response

However, this does not work. After looking around for a while, I believe I should change something on both ends – the Javascript and the python/Django code – but I'm unclear what exactly.

For Python, my main concern is in the use of cStringIO (especially the fact that I cannot execute close on jsonFile before returning without prompting a "ValueError: I/O operation on closed file").

Maybe I should also be using a FileWrapper (like in this post), but I get identical results with and without it.

For Javascript, I'm not sure what should go into my success handler function.

Any pointers would be greatly appreciated!

like image 805
arturomp Avatar asked May 21 '12 22:05

arturomp


1 Answers

The classic solution for this is to use an hidden iframe.

In your urls.py

url(r'^test/getFile', 'getFile')

In your views.py

def getFile(request):
    fileContent = "Your name is %s" % request.GET['name']
    res = HttpResponse(fileContent)
    res['Content-Disposition'] = 'attachment; filename=yourname.txt'
    return res

On your page

<script type="text/javascript">
    var data = {name: 'Jon'};
    $(function(){
        $("body").append('<iframe src="/test/getFile?'+ $.param(data) + '" style="display: none;" ></iframe>');
    });
</script>
like image 124
xbtsw Avatar answered Oct 16 '22 10:10

xbtsw