Załaduj ponownie aplikację Flask po zmianie pliku szablonu

96

Domyślnie, uruchamiając aplikację Flask przy użyciu wbudowanego serwera ( Flask.run), monitoruje ona swoje pliki w języku Python i automatycznie ponownie ładuje aplikację, jeśli jej kod ulegnie zmianie:

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

Niestety, wydaje się, że działa to tylko dla plików * .py i nie wydaje mi się, aby znaleźć sposób na rozszerzenie tej funkcji na inne pliki. Przede wszystkim niezwykle przydatne byłoby ponowne uruchomienie aplikacji Flask po zmianie szablonu . Straciłem rachubę, ile razy majstrowałem przy znacznikach w szablonach i byłem zdezorientowany, nie widząc żadnych zmian, tylko po to, aby dowiedzieć się, że aplikacja nadal używa starej wersji szablonu Jinja.

Czy jest więc sposób na umieszczenie plików monitora Flask w katalogu szablonów , czy też wymaga to zanurzenia się w źródłach frameworka?

Edycja : używam Ubuntu 10.10. Tak naprawdę nie próbowałem tego na żadnej innej platformie.


Po dalszym dochodzeniu odkryłem, że zmiany w szablonach rzeczywiście aktualizowane w czasie rzeczywistym, bez ponownego ładowania samej aplikacji. Wydaje się jednak, że dotyczy to tylko tych szablonów, które są przekazywane do flask.render_template.

Tak się jednak składa, że ​​w swojej aplikacji mam całkiem sporo sparametryzowanych komponentów wielokrotnego użytku, których używam w szablonach Jinja. Są zaimplementowane jako {% macro %}s, znajdują się w dedykowanych „modułach” i są umieszczane {% import %}na rzeczywistych stronach. Wszystko ładne i SUCHE ... poza tym, że te zaimportowane szablony najwyraźniej nigdy nie są sprawdzane pod kątem modyfikacji, ponieważ w ogóle nie przechodzą render_template.

(Co ciekawe, nie dzieje się tak w przypadku szablonów wywoływanych za pośrednictwem {% extends %}. {% include %}Nie mam pojęcia, ponieważ tak naprawdę ich nie używam).

Podsumowując, korzenie tego zjawiska wydają się leżeć gdzieś pomiędzy Jinją a Flaskiem lub Werkzeugiem. Myślę, że to może uzasadniać podróż do śledzenia błędów dla któregokolwiek z tych projektów :) W międzyczasie zaakceptowałem jd. odpowiedź, ponieważ właśnie tego użyłem - i działa jak urok.

Xion
źródło
3
Upewnij się, że aplikacja została skonfigurowana z DEBUG = True, zobacz dokumentację .
Alex Morega

Odpowiedzi:

67

Z mojego doświadczenia render_template()wynika , że szablony nie wymagają nawet ponownego uruchamiania aplikacji w celu odświeżenia, ponieważ powinny być ładowane z dysku przy każdym wywołaniu. Może jednak twoje szablony są używane inaczej.

Aby przeładować aplikację, gdy zmieniają się szablony (lub jakikolwiek inny plik), możesz przekazać extra_filesargument do Flask().run()kolekcji nazw plików do obejrzenia: każda zmiana w tych plikach spowoduje ponowne załadowanie .

Przykład:

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)

Zobacz tutaj: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple

jd.
źródło
Dobry towar! Przyznaję, że przegapiłem link w dokumentacji, Flask.runktóra prowadzi do dokumentów Werkzeug. Ale ta konkretna opcja wydaje się wystarczająco użyteczna, aby przynajmniej wspomnieć o niej w dokumentach Flaska.
Xion
Jeśli ktoś napotka błąd, który mówi No such file or directory, spróbuj użyć ścieżki względnej, jak w:extra_dirs = ['./directory/to/watch',]
Kevin
3
Jeśli ty też nie wiesz path, co jest, to tak os.path. pomyślałem, że warto o tym wspomnieć
bjesus
Aby uzyskać informacje na temat automatycznego ponownego ładowania po zmianie plików statycznych, zobacz to .
simanacci
1
Masz jakiś pomysł, jak określić dodatkowe pliki podczas uruchamiania flask runz wiersza poleceń?
Michael Scheper
148

możesz użyć

TEMPLATES_AUTO_RELOAD = True

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

Czy sprawdzać modyfikacje źródła szablonów i ładować je automatycznie. Domyślną wartością jest None, co oznacza, że ​​Flask sprawdza oryginalny plik tylko w trybie debugowania.

Loris
źródło
11
To rozwiązanie konwencjonalne, poparte dokumentacją, proste do zrozumienia i łatwe do wdrożenia. Należy to zaakceptować!
Carolyn Conway
Próbowałem tej odpowiedzi, ale działa tylko raz, po kolejnym odświeżeniu nie zadziała
medev21
3
Tylko uwaga dla innych: tak zrobiłem app.config['TEMPLATES_AUTO_RELOAD'] = Trueiz jakiegoś powodu spodziewałem się, że serwer automatycznie uruchomi się ponownie po zmianie szablonu, tak jak w trybie debugowania. Nie uruchamia się ponownie, ale aktualizuje szablon, który renderuje.
cs01
3
Czy jest jakiś powód, dla którego to nie działałoby dla 0.12? lub inne ustawienie, które uniemożliwiłoby to prawidłowe ustawienie?
user805981
3
@Federer Wygląda na to, że nie działa tak jak kiedyś ... Wcześniej wykryłby zmiany w katalogu szablonów i podkatalogach i przeładowałby serwer ... Czy to coś nowego w 0.12, że zmienił się?
user805981
55

Podczas pracy z jinjaszablonami musisz ustawić niektóre parametry. W moim przypadku z pythonem3 rozwiązałem to za pomocą następującego kodu:

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
źródło
1
Uratowałeś mój rozsądek. Dziękuję Ci.
Nostalg.io
Mnie też ciężko było z tym problemem. Cieszę się, że mogłem pomóc;)
silgon
To działa dla mnie na kolbie 1.0.2, ale nie mam argumentu hosta.
Enrico Borba
Tak, @EnricoBorba, prawdopodobnie nie będziesz tego potrzebować. Zwykle go używam, ponieważ debuguję lokalnie za pomocą dockera, a czasami aplikacja musi być dostępna z innego kontenera. Trochę odniesienia
silgon
@silgon Yea, rozumiem. Głównie dodawałem komentarz, żeby wyjaśnić, co zadziałało przy nowej instalacji Flaska w wersji 1.0.2
Enrico Borba
18

U mnie działa dobrze:

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

Zobacz więcej na http://flask.pocoo.org/docs/1.0/config/

Nikandr Marhal
źródło
10

Właściwie u mnie TEMPLATES_AUTO_RELOAD = Truenie działa (wersja 0.12). Używam jinja2 i co zrobiłem:

  1. Utwórz funkcję before_request

    def before_request():
        app.jinja_env.cache = {}
    
  2. Zarejestruj go w aplikacji

    app.before_request(before_request)
    
  3. Otóż ​​to.

dikkini
źródło
3
Garret, nie testowałem bez tych opcji.
dikkini
Krok 3 nie jest konieczny, dla mnie zadziałał bardzo dobrze.
Ricardo Ribeiro
4

To, co zadziałało, to po prostu dodanie tego:

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

( zaczerpnięte z odpowiedzi @ dikkini )

Garrett
źródło
2

Używając najnowszej wersji Flaska w systemie Windows, używając polecenia uruchom i debugowania ustawionego na true; Flask nie musi być resetowany, aby zmiany w szablonach zostały wprowadzone. Wypróbuj Shift + F5 (lub Shift i przycisk ponownego ładowania), aby upewnić się, że nic nie jest buforowane.

Drakekin
źródło
2

Zaktualizowano w czerwcu 2019 r .:

Kolba CLI jest zalecany przez app.run () uruchamiania serwera dev, więc jeśli chcemy korzystać z CLI następnie przyjętego rozwiązania nie mogą być użyte.

Korzystanie z rozwojowej wersji Flask (1.1) w chwili pisania tego tekstu pozwala nam ustawić zmienną środowiskową FLASK_RUN_EXTRA_FILES, która skutecznie robi to samo, co zaakceptowana odpowiedź.

Zobacz ten problem na githubie .

Przykładowe użycie:

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

w Linuksie. Aby określić wiele dodatkowych plików, oddziel ścieżki plików dwukropkami. , np

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

Interfejs CLI obsługuje również --extra-filesargument z Flask 1.1.

za granicą
źródło
drobna aktualizacja. link do 'flask CLI' wymaga aktualizacji do aktualnej wersji. flask.palletsprojects.com/en/1.1.x/cli w przeciwnym razie dzięki :)
CodingMatters
1

Szablony są ładowane automatycznie, dlaczego nie ctrl+f5odświeżać strony internetowej, ponieważ przeglądarki internetowe zwykle oszczędzają pamięć podręczną.

Chief Shiv
źródło