В функции flask, которая возвращает `send_file`, код не запускается при последующих запросах, но файл все равно загружается. Почему? - PullRequest
0 голосов
/ 06 апреля 2020

Я использую код Flask со следующим маршрутом:

@app.route('/download')
def download_file():
    path = "certificate.docx"
    print("certificate printed")
    print(os.getcwd())
    return send_file(path, as_attachment=True)

HTML Код:

<p>
<a href="{{ url_for('.download_file') }}">Download</a>
</p>

Этот фрагмент кода выполняется для загрузки файла named certificate.docx.

Проблема в том, что операторы print внутри функции download_file() на самом деле не выполняются, но все же позволяет мне загрузить файл.

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

Эта проблема, скорее всего, вызвана кэшированием, встроенным в Flask. Это устанавливает заголовок Cache-Control и применяется к stati c файлам, обслуживаемым Flask, но также к функциям send_file и send_from_directory. (ссылка) .

Это объясняет поведение загрузки файла, но операторы печати не выполняются. На самом деле этот запрос даже не будет попадать на сервер.

Вы можете визуализировать это на вкладке сети инструментов dev:

caching enabled


Вы можете отключить это, установив следующую конфигурационную переменную в своем приложении:

app.config['SEND_FILE_MAX_AGE_DEFAULT'] = -1

Значение -1 отключает кэширование.

Возможно, вам придется очистить кэш браузера, чтобы этот параметр вступил в силу или изменил URL-адрес вашей конечной точки /download, хотя это неудобно.

Обратите внимание на разницу, если она установлена:

caching disabled.

0 голосов
/ 06 апреля 2020

Я предполагаю, что вы хотите, чтобы операторы печати отображались в вашем HTML. Я прошу прощения, если это не то, что вы ищете.

Первое, что делает print в вашем примере - это вывод текста на сервер, поэтому текст никогда не отправляется на ваш HTML.

* 1004. * Для отправки сообщений на ваш HTML вы можете импортировать flash из flask. Функция flash отправит сообщение на ваш HTML, где вы можете получить код с get_flashed_messages().

Пример

Вот пример, адаптированный из Flask Документы .

Ниже мы делаем несколько вещей.

  1. Вместо print мы используем flash. Первый аргумент, переданный flash, является сообщением. ("certificate printed" или os.getcwd()) Вторым аргументом является категория сообщения. ("download_file") Обратите внимание, что категория может быть совершенно произвольной, если в шаблоне используется одна и та же категория.
  2. Ниже ссылки в HTML. Мы вызываем get_flashed_messages и присваиваем его переменной download_msgs. Единственный аргумент в этом случае - category_filter=["download_file"]. При этом будут получены все сообщения, которые мы отправили с flash ранее, и останутся только сообщения с категорией "download_file".
  3. Мы проверяем сообщения с {% if download_msgs %}, l oop над сообщениями с {% for message in download_msgs %} и отображать каждое сообщение.

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>

Этот пример груб, но я надеюсь, что это отвечает на ваш вопрос

Резюме

  • Чтобы отправлять сообщения из вашего приложения flask в ваш код HTML, вы можете использовать функцию flash в своем приложении flask.
  • Чтобы получать сообщения из вашего приложения flask на ваш код HTML, вы можете использовать функцию get_flashed_messages в своем коде HTML.
  • Вы можете использовать категории для различения вспыхнувшего Сообщения. Используйте второй аргумент flash в вашем flask приложении. Используйте аргумент category_filter ключевого слова get_flashed_messages в своем коде HTML.
...