问题
I am using a Flask Code with the following route:
@app.route('/download')
def download_file():
path = "certificate.docx"
print("certificate printed")
print(os.getcwd())
return send_file(path, as_attachment=True)
HTML Code:
<p>
<a href="{{ url_for('.download_file') }}">Download</a>
</p>
This piece of code is being executed to download a file named certificate.docx
.
The problem is that the print statements inside the function download_file()
are not actually being executed, yet it still allows me to download the file.
回答1:
This problem is most likely caused by caching which is built into Flask. This sets the Cache-Control
header, and applies to static files served by Flask, but also the send_file
and send_from_directory
functions. (reference).
This would explain the behaviour of the file downloading, but the print statements not running. In fact that request won't even be hitting the server.
You can visualise this on the network tab of the dev tools:
You can disable this by setting the following config variable on your app:
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = -1
The -1
value disables caching.
You may have to actually clear the browser cache for this setting to take affect, or change the URL of your /download
endpoint, although this is inconvenient.
Note the difference once this is set:
回答2:
I am assuming you want the print statements to show in your HTML. I apologize if that is not what you are looking for.
First what print is doing in your example is outputting text on the server, so the text never is sent to your HTML.
To send messages to your HTML you can import flash
from flask. The flash
function will send a message to your HTML where you can receive code with get_flashed_messages()
.
Example
Here is an example adapted from the Flask Docs.
Below we do a few things.
- Instead of
print
, we useflash
. The first argument passed toflash
is the message. ("certificate printed"
oros.getcwd()
) The second argument is the category of message. ("download_file"
) Note that the category can be completely arbitrary as long as the same category is used in the template. - Below the link in the HTML. We call
get_flashed_messages
and assign it to a variabledownload_msgs
. The only argument in this case iscategory_filter=["download_file"]
. This will get all the messages we sent withflash
earlier and keep only the ones with the"download_file"
category. - We check for messages with
{% if download_msgs %}
, loop over messages with{% for message in download_msgs %}
, and display each message.
Flask:
from flask import Flask, flash, send_file
app = Flask(__name__)
@app.route('/download')
def download_file():
path = "certificate.docx"
flash("certificate printed", "download_file")
flash(os.getcwd(), "download_file")
return send_file(path, as_attachment=True)
HTML:
<p>
<a href="{{ url_for('.download_file') }}">Download</a>
{% with download_msgs = get_flashed_messages(category_filter=["download_file"]) %}
{% if download_msgs %}
<ul class=flashes>
{% for message in download_msgs %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
This example is crude, but I hope it answers your question
Summary
- To send messages from your flask app to your HTML code, you can use the
flash
function in your flask app. - To receive messages from your flask app to your HTML code, you can use the
get_flashed_messages
function in your HTML code. - You can use categories to differentiate flashed messages. Use the second argument of
flash
in your flask app. Use the category_filter keyword argument ofget_flashed_messages
in your HTML code.
来源:https://stackoverflow.com/questions/61066083/in-a-flask-function-which-returns-send-file-the-code-doesnt-appear-to-run-on