Перезагрузите приложение Flask при изменении файла шаблона


96

По умолчанию при запуске приложения Flask с использованием встроенного server ( Flask.run) он отслеживает свои файлы Python и автоматически перезагружает приложение, если его код изменяется:

* Detected change in '/home/xion/hello-world/app.py', reloading
* Restarting with reloader

К сожалению, похоже, что это работает только для файлов * .py , и я, похоже, не нахожу способа расширить эту функциональность на другие файлы. В частности, было бы чрезвычайно полезно перезапустить приложение Flask при изменении шаблона . Я потерял счет, сколько раз возился с разметкой в ​​шаблонах и сбивался с толку, не видя никаких изменений, только чтобы узнать, что приложение все еще использует старую версию шаблона Jinja.

Итак, есть ли способ разместить файлы монитора Flask в каталоге шаблонов , или это требует погружения в исходный код фреймворка?

Изменить : я использую Ubuntu 10.10. На самом деле я не пробовал это ни на каких других платформах.


После дальнейших исследований, я обнаружил , что изменения в шаблонах действительно будут обновлены в режиме реального времени, без перезагрузки самого приложения. Однако, похоже, это применимо только к тем шаблонам, которые передаются flask.render_template.

Но так уж получилось, что в моем приложении довольно много параметризованных компонентов многократного использования, которые я использую в шаблонах Jinja. Они реализованы как {% macro %}s, находятся в выделенных «модулях» и {% import %}превращаются в реальные страницы. Все красиво и СУХОЙ ... за исключением того, что эти импортированные шаблоны, по-видимому, никогда не проверяются на наличие изменений, поскольку они вообще не проходят render_template.

(Любопытно, что этого не происходит с шаблонами, вызываемыми через {% extends %}. Что касается {% include %}, я понятия не имею, так как на самом деле я их не использую.)

Итак, корни этого явления, кажется, лежат где-то между Jinja и Flask или Werkzeug. Думаю, для любого из этих проектов может потребоваться поездка в систему отслеживания ошибок :) Тем временем я принял jd. ответ, потому что я действительно использовал это решение - и оно работает как шарм.


3
Убедитесь, что приложение настроено с DEBUG = True, см. Документацию .
Alex Morega 01

Ответы:


67

По моему опыту, шаблоны даже не нуждаются в перезапуске приложения для обновления, поскольку они должны загружаться с диска каждый раз при render_template()вызове. Возможно, ваши шаблоны используются по-другому.

Чтобы перезагрузить приложение при изменении шаблонов (или любого другого файла), вы можете передать extra_filesаргумент Flask().run()коллекции имён файлов, которую нужно отслеживать: любое изменение в этих файлах вызовет перезагрузку.

Пример:

from os import path, walk

extra_dirs = ['directory/to/watch',]
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
    for dirname, dirs, files in walk(extra_dir):
        for filename in files:
            filename = path.join(dirname, filename)
            if path.isfile(filename):
                extra_files.append(filename)
app.run(extra_files=extra_files)

См. Здесь: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple


Хорошая вещь! Признаюсь, я пропустил ссылку в документации, Flask.runкоторая ведет к документации Werkzeug. Но эта конкретная опция кажется достаточно полезной, чтобы хотя бы упомянуть о ней в документации Flask.
Xion

Если кто-нибудь столкнется с ошибкой, в которой говорится No such file or directory, попробуйте использовать относительный путь, как в:extra_dirs = ['./directory/to/watch',]
Кевин

3
Если вы тоже не знаете, что pathесть, то это os.path. подумал, что стоит упомянуть
bjesus 03

Для автоматической перезагрузки после изменения статических файлов см. Это .
simanacci

1
Есть идеи, как указать дополнительные файлы при запуске flask runиз командной строки?
Майкл Шепер

147

ты можешь использовать

TEMPLATES_AUTO_RELOAD = True

С http://flask.pocoo.org/docs/1.0/config/

Следует ли проверять наличие изменений в источнике шаблона и автоматически перезагружать его. По умолчанию значение равно None, что означает, что Flask проверяет исходный файл только в режиме отладки.


11
Это стандартное решение, подкрепленное документацией, простое для понимания и легкое в реализации. Это нужно принять!
Кэролайн Конвей,

Я пробовал этот ответ, но работает только один раз, после другого обновления он не сработает
medev21

3
Просто примечание для других: я это сделал app.config['TEMPLATES_AUTO_RELOAD'] = Trueи по какой-то причине ожидал увидеть автоматический перезапуск сервера при изменении шаблона, как это происходит в режиме отладки. Он не перезагружается, но ДЕЙСТВИТЕЛЬНО обновляет шаблон, который он отображает.
cs01 01

3
Есть ли причина, по которой это не работает для 0,12? или какой-то другой параметр, который помешал бы правильной настройке?
user805981

3
@Federer Похоже, что он работает не так, как раньше ... Раньше он обнаруживал изменения в каталоге шаблонов и подкаталогах и перезагружал сервер ... Это что-то новое в 0.12, что изменилось?
user805981 02

55

Когда вы работаете с jinjaшаблонами, вам необходимо установить некоторые параметры. В моем случае с python3 я решил это с помощью следующего кода:

if __name__ == '__main__':
    app.jinja_env.auto_reload = True
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.run(debug=True, host='0.0.0.0')

1
Ты спас мне рассудок. Спасибо.
Nostalg.io

Мне тоже было нелегко с этой проблемой. Я рад, что смог помочь;)
silgon

У меня это работает на flask 1.0.2, но у меня нет аргумента хоста.
Enrico Borba

Да, @EnricoBorba, тебе это, наверное, не понадобится. Обычно я использую его, потому что я отлаживаю локально с помощью докера, и иногда к приложению требуется доступ из другого контейнера. Some Reference
Silgon

@silgon Да, я понимаю. В основном я просто добавлял комментарий, чтобы прояснить, что работает при новой установке Flask версии 1.0.2
Энрико Борба


10

Собственно у меня TEMPLATES_AUTO_RELOAD = Trueне работает (версия 0.12). Я использую jinja2 и что уже сделал:

  1. Создать функцию before_request

    def before_request():
        app.jinja_env.cache = {}
    
  2. Зарегистрируйте его в приложении

    app.before_request(before_request)
    
  3. Вот и все.


3
Гаррет, без этих опций я не тестировал.
dikkini

Шаг 3 на самом деле не нужен, мне он очень понравился.
Рикардо Рибейро,

4

Для меня сработало просто добавление этого:

@app.before_request
def before_request():
    # When you import jinja2 macros, they get cached which is annoying for local
    # development, so wipe the cache every request.
    if 'localhost' in request.host_url or '0.0.0.0' in request.host_url:
        app.jinja_env.cache = {}

( взято из ответа @dikkini )


2

Используя последнюю версию Flask в Windows, используя команду run и отладку, установленную на true; Flask не нужно сбрасывать, чтобы изменения в шаблонах вступили в силу. Попробуйте Shift + F5 (или Shift плюс кнопка перезагрузки), чтобы убедиться, что ничего не кэшируется.


2

Обновлено по состоянию на июнь 2019 г .:

CLI колбу рекомендуется использовать вместо app.run () для запуска сервера разработки, поэтому, если мы хотим использовать интерфейс командной строки, принятое решение использовать нельзя.

Использование разрабатываемой версии Flask (1.1) на момент написания этой статьи позволяет нам установить переменную среды FLASK_RUN_EXTRA_FILES, которая эффективно выполняет то же самое, что и принятый ответ.

См. Эту проблему на github .

Пример использования:

export FLASK_RUN_EXTRA_FILES="app/templates/index.html"
flask run

в Linux. Чтобы указать несколько дополнительных файлов, разделите пути к файлам двоеточиями. , например

export FLASK_RUN_EXTRA_FILES="app/templates/index.html:app/templates/other.html"

CLI также поддерживает --extra-filesаргумент, начиная с Flask 1.1.


незначительное обновление. ссылка на «flask CLI» требует обновления до текущей версии. flask.palletsprojects.com/en/1.1.x/cli, в противном случае спасибо :)
CodingMatters


1

Шаблоны перезагружаются автоматически, почему бы не ctrl+f5обновить веб-страницу, потому что веб-браузеры обычно сохраняют кеш.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.