Return a download and rendered page in one Flask response

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.


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>

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.