Перезавантажте програму Flask, коли файл шаблону змінюється


95

За замовчуванням, під час запуску програми Flask за допомогою вбудованого сервера ( 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 %}, я не маю уявлення, оскільки я насправді їх не використовую.)

Отже, підсумовуючи, коріння цього явища, здається, лежить десь між Джинджею та Фляшкою чи Веркцогом. Думаю, це може вимагати поїздки до відстежувача помилок для будь-якого з цих проектів :) Тим часом я прийняв jd. відповідь, тому що це рішення, яке я насправді використовував - і воно працює як шарм.


3
Переконайтеся, що програма налаштована на DEBUG = True, див . Документи .
Алекс Морега 01.03.12

Відповіді:


65

З мого досвіду, шаблони навіть не потребують оновлення програми для перезапуску, оскільки їх слід завантажувати з диска щоразу, коли 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

Для автоматичного перезавантаження після зміни статичних файлів див. Це .
simanacci

1
Будь-яка ідея, як вказати додаткові файли під час запуску flask runз командного рядка?
Michael Scheper

143

ви можете використовувати

TEMPLATES_AUTO_RELOAD = True

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

Чи потрібно перевіряти модифікації джерела шаблону та перезавантажувати його автоматично. За замовчуванням значення None, що означає, що Flask перевіряє оригінальний файл лише в режимі налагодження.


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

Я спробував цю відповідь, але працює лише один раз, після чергового оновлення це не спрацювало
medev21

3
Просто примітка для інших: я це зробив app.config['TEMPLATES_AUTO_RELOAD'] = True, і з якихось причин очікував, що сервер автоматично перезапуститься, коли шаблон зміниться, як це робиться в режимі налагодження. Він не перезапускається, але ПОВТОРНО оновлює шаблон, який він відображає.
cs01

3
Будь-яка причина, чому це не працює для 0,12? чи якесь інше налаштування, яке перешкоджало б правильному налаштуванню?
user805981

3
@Federer Здається, це не працює як раніше ... Раніше він виявив би зміни у каталозі шаблонів та підкаталогах, і він би перезавантажив сервер .... Це щось нове в 0.12, що змінився?
user805981 02

54

Коли ви працюєте з 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

Це працює для мене в колбі 1.0.2, але я не маю аргументу хоста.
Енріко Борба

Так @EnricoBorba, вам це, мабуть, не знадобиться. Зазвичай я використовую його, оскільки налагоджую локально за допомогою docker, а іноді до програми потрібно отримати доступ з іншого контейнера. Деякі посилання
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, використовуючи команду запуску та налагодження, встановлену на true; Колбу не потрібно скидати, щоб зміни в шаблонах були введені в дію. Спробуйте Shift + F5 (або Shift плюс кнопка перезавантаження), щоб переконатися, що він не кешований.



1

Оновлено станом на червень 2019 року:

CLI колби рекомендується над app.run () для запуску сервера розробника, тому якщо ми хочемо використовувати CLI , то прийняте рішення не може бути використаний.

Використання версії 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.