Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a download and rendered page in one Flask response

Tags:

python

flask

I want to return a rendered page and a downloadable file as a response to a request. I've tried to return a tuple of both responses, but it doesn't work. How can I serve the download and the page?

return response, render_template('database.html')
return render_template('database.html'), response

Is Flask capable of handling such a scenario? Seems like a commonplace problem, I simply want to send a file back for download, then render the page.

like image 289
Kenny Powers Avatar asked Nov 30 '15 23:11

Kenny Powers


2 Answers

You cannot return multiple responses to a single request. Instead, generate and store the files somewhere, and serve them with another route. Return your rendered template with a url for the route to serve the file.

@app.route('/database')
def database():
    # generate some file name
    # save the file in the `database_reports` folder used below
    return render_template('database.html', filename=stored_file_name)

@app.route('/database_download/<filename>')
def database_download(filename):
    return send_from_directory('database_reports', filename)

In the template, use url_for to generate the download url.

<a href="{{ url_for('database_download', filename=filename) }}">Download</a>
like image 142
davidism Avatar answered Nov 04 '22 02:11

davidism


I was just looking for something easiers so here the solution for people who look for something even simpler:

A pretty easy and dirty solution would be the usage of javascript.

For example like this:

<button onclick="goBack()"><a href="{{ url_for('export') }}">Export</a></button>

<script>
function goBack() {
  window.history.back();
}
</script>

The JS will open the browser window which you were before, what means it stays in the same. The download is initiated by the ref. The ref then leads to your flask-route where the function is.

like image 1
grumpyp Avatar answered Nov 04 '22 02:11

grumpyp