Muat ulang aplikasi Flask saat file template berubah

96

Secara default, ketika menjalankan aplikasi Flask menggunakan built-in server ( Flask.run), ia memonitor file Python-nya dan secara otomatis memuat ulang aplikasi jika kodenya berubah:

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

Sayangnya, ini tampaknya hanya berfungsi untuk file * .py , dan saya sepertinya tidak menemukan cara untuk memperluas fungsionalitas ini ke file lain. Terutama, akan sangat berguna jika Flask memulai ulang aplikasi saat template berubah. Saya tidak dapat menghitung berapa kali saya mengutak-atik markup di template dan menjadi bingung karena tidak melihat perubahan apa pun, hanya untuk mengetahui bahwa aplikasi tersebut masih menggunakan template Jinja versi lama.

Jadi, apakah ada cara untuk memiliki file monitor Flask di direktori templates , atau apakah itu membutuhkan masuk ke sumber framework?

Edit : Saya menggunakan Ubuntu 10.10. Belum pernah mencobanya di platform lain.


Setelah penyelidikan lebih lanjut, saya telah menemukan bahwa perubahan dalam template memang sedang diperbarui secara real time, tanpa reload aplikasi itu sendiri. Namun, ini tampaknya hanya berlaku untuk template yang diteruskan flask.render_template.

Tapi kebetulan di aplikasi saya, saya memiliki cukup banyak komponen parameter yang dapat digunakan kembali yang saya gunakan di template Jinja. Mereka diimplementasikan sebagai {% macro %}s, berada dalam "modul" khusus dan {% import %}diubah menjadi halaman sebenarnya. Semuanya bagus dan KERING ... kecuali bahwa templat yang diimpor itu tampaknya tidak pernah diperiksa untuk modifikasi, karena tidak lolos render_templatesama sekali.

(Anehnya, ini tidak terjadi untuk template yang dipanggil melalui {% extends %}. Adapun {% include %}, saya tidak tahu karena saya tidak benar-benar menggunakannya.)

Jadi untuk menyimpulkan, akar dari fenomena ini tampaknya terletak di antara Jinja dan Flask atau Werkzeug. Saya kira ini mungkin memerlukan perjalanan ke pelacak bug untuk salah satu proyek tersebut :) Sementara itu, saya telah menerima jd. jawabannya karena itulah solusi yang sebenarnya saya gunakan - dan berfungsi dengan sangat baik.

Xion
sumber
3
Pastikan aplikasi dikonfigurasi dengan DEBUG = True, lihat dokumennya .
Alex Morega

Jawaban:

67

Dalam pengalaman saya, templat bahkan tidak memerlukan aplikasi untuk dimulai ulang untuk disegarkan, karena templat harus dimuat dari disk setiap kali render_template()dipanggil. Mungkin template Anda digunakan secara berbeda.

Untuk memuat ulang aplikasi Anda saat template berubah (atau file lainnya), Anda dapat meneruskan extra_filesargumen ke Flask().run(), kumpulan nama file yang harus diperhatikan: setiap perubahan pada file tersebut akan memicu reloader.

Contoh:

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)

Lihat di sini: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple

jd.
sumber
Barang bagus! Saya akui saya melewatkan tautan dalam dokumentasi Flask.runyang mengarah ke dokumen Werkzeug. Tetapi opsi khusus ini tampaknya cukup berguna untuk setidaknya disebutkan dalam dokumen Flask.
Xion
Jika ada yang menemui kesalahan yang mengatakan No such file or directory, coba gunakan jalur relatif seperti di:extra_dirs = ['./directory/to/watch',]
Kevin
3
Jika Anda juga bingung tentang apa pathitu os.path. pikir itu layak untuk disebutkan
bjesus
Untuk memuat ulang otomatis setelah mengubah file statis, lihat ini .
simanacci
1
Ada ide bagaimana menentukan file tambahan saat menjalankan flask rundari baris perintah?
Michael Scheper
147

kamu bisa memakai

TEMPLATES_AUTO_RELOAD = True

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

Apakah akan memeriksa modifikasi sumber template dan memuatnya kembali secara otomatis. Secara default nilainya adalah None yang berarti Flask hanya memeriksa file asli dalam mode debug.

Kukang
sumber
11
Solusi ini konvensional, didukung oleh dokumentasi, sederhana untuk dipahami, dan mudah diimplementasikan. Itu harus diterima!
Carolyn Conway
Saya mencoba jawaban ini tetapi hanya berfungsi sekali, setelah penyegaran lagi itu tidak akan berhasil
medev21
3
Hanya catatan untuk orang lain: Saya melakukannya app.config['TEMPLATES_AUTO_RELOAD'] = True, dan untuk beberapa alasan diharapkan melihat server restart otomatis ketika template berubah, seperti yang terjadi dalam mode debug. Itu tidak memulai ulang, tetapi TIDAK memperbarui template yang direndernya.
cs01
3
Adakah alasan mengapa ini tidak akan berhasil untuk 0,12? atau beberapa pengaturan lain yang akan mencegah pengaturan ini dengan benar?
pengguna805981
3
@Federer Tampaknya tidak berfungsi seperti dulu ... Sebelumnya, akan mendeteksi perubahan di direktori template dan sub direktori dan akan memuat ulang server .... Apakah ini sesuatu yang baru di 0.12 yang berubah?
pengguna805981
55

Saat Anda bekerja dengan jinjatemplate, Anda perlu mengatur beberapa parameter. Dalam kasus saya dengan python3, saya menyelesaikannya dengan kode berikut:

if __name__ == '__main__':
    app.jinja_env.auto_reload = True
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.run(debug=True, host='0.0.0.0')
silgon
sumber
1
Anda menyelamatkan kewarasan saya. Terima kasih.
Nostalg.io
Saya juga mengalami kesulitan dengan masalah itu. Saya senang saya bisa membantu;)
silgon
Ini bekerja untuk saya di flask 1.0.2, tapi saya tidak memiliki argumen host.
Enrico Borba
Ya @EnricoBorba, Anda mungkin tidak akan membutuhkannya. Saya biasanya menggunakannya karena saya men-debug secara lokal dengan buruh pelabuhan, dan terkadang aplikasi perlu diakses dari penampung lain. Beberapa Referensi
silgon
@silgon Ya, saya mengerti. Saya hanya menambahkan komentar untuk memperjelas tentang apa yang berhasil pada pemasangan baru Flask versi 1.0.2
Enrico Borba
18

Bagi saya bekerja dengan baik:

 from flask import Flask, render_template, request, url_for, redirect
 app = Flask(__name__)
 app.config["TEMPLATES_AUTO_RELOAD"] = True

Lihat lebih lanjut di http://flask.pocoo.org/docs/1.0/config/

Nikandr Marhal
sumber
10

Sebenarnya bagi saya TEMPLATES_AUTO_RELOAD = Truetidak berfungsi (versi 0,12). Saya menggunakan jinja2 dan apa yang telah saya lakukan:

  1. Buat fungsi before_request

    def before_request():
        app.jinja_env.cache = {}
    
  2. Daftarkan di aplikasi

    app.before_request(before_request)
    
  3. Itu dia.

dikkini
sumber
3
Garret, saya tidak menguji tanpa opsi ini.
dikkini
Langkah 3 tidak terlalu penting, ini bekerja dengan sangat baik bagi saya.
Ricardo Ribeiro
4

Apa yang berhasil bagi saya hanyalah menambahkan ini:

@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 = {}

( diambil dari jawaban @ dikkini )

Garrett
sumber
2

Menggunakan versi terbaru Flask di Windows, menggunakan perintah run dan debug disetel ke true; Flask tidak perlu diatur ulang agar perubahan pada template dapat diterapkan. Coba Shift + F5 (atau Shift plus tombol muat ulang) untuk memastikan tidak ada yang di-cache.

Drakekin
sumber
2

Diperbarui per Juni 2019:

The termos CLI dianjurkan lebih app.run () untuk menjalankan server dev, jadi jika kita ingin menggunakan CLI maka solusi yang diterima tidak dapat digunakan.

Menggunakan versi pengembangan Flask (1.1) pada tulisan ini memungkinkan kita untuk menyetel variabel lingkungan FLASK_RUN_EXTRA_FILES yang secara efektif melakukan hal yang sama seperti jawaban yang diterima.

Lihat masalah github ini .

Contoh penggunaan:

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

di Linux. Untuk menentukan beberapa file tambahan, pisahkan jalur file dengan titik dua. , mis

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

CLI juga mendukung --extra-filesargumen mulai dari Flask 1.1.

luar negeri
sumber
pembaruan kecil. tautan ke 'flask CLI' perlu diperbarui ke versi saat ini. flask.palletsprojects.com/en/1.1.x/cli sebaliknya terima kasih :)
CodingMatters
1

Template dimuat ulang secara otomatis, mengapa tidak melakukan ctrl+f5refresh halaman web, karena browser web biasanya menyimpan cache.

Kepala Shiv
sumber