Flask löst einen TemplateNotFound-Fehler aus, obwohl eine Vorlagendatei vorhanden ist

101

Ich versuche die Datei zu rendern home.html. Die Datei ist in meinem Projekt vorhanden, aber ich bekomme sie immer wieder, jinja2.exceptions.TemplateNotFound: home.htmlwenn ich versuche, sie zu rendern. Warum kann Flask meine Vorlage nicht finden?

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('home.html')
/myproject
    app.py
    home.html
Srdan Ristic
quelle

Antworten:

211

Sie müssen Ihre Vorlagendateien am richtigen Speicherort erstellen. in demtemplates Unterverzeichnis neben Ihrem Python-Modul.

Der Fehler zeigt an, dass sich keine home.htmlDatei im templates/Verzeichnis befindet. Stellen Sie sicher, dass Sie dieses Verzeichnis im selben Verzeichnis wie Ihr Python-Modul erstellt haben und dass Sie tatsächlich eine home.htmlDatei in dieses Unterverzeichnis gestellt haben. Wenn Ihre App ein Paket ist, sollte der Vorlagenordner innerhalb des Pakets erstellt werden.

myproject/
    app.py
    templates/
        home.html
myproject/
    mypackage/
        __init__.py
        templates/
            home.html

Wenn Sie Ihren Vorlagenordner anders benannt haben templatesund ihn nicht in den Standard umbenennen möchten, können Sie Flask alternativ anweisen, dieses andere Verzeichnis zu verwenden.

app = Flask(__name__, template_folder='template')  # still relative to module

Sie können Flask bitten, zu erklären, wie versucht wurde, eine bestimmte Vorlage zu finden, indem Sie die EXPLAIN_TEMPLATE_LOADINGOption auf setzen True. Für jede geladene Vorlage erhalten Sie einen Bericht, der auf Ebene der Flascheapp.logger protokolliert wird INFO.

So sieht es aus, wenn eine Suche erfolgreich ist. In diesem Beispiel erweitert die foo/bar.htmlVorlage die base.htmlVorlage, sodass zwei Suchvorgänge ausgeführt werden:

[2019-06-15 16:03:39,197] INFO in debughelpers: Locating template "foo/bar.html":
    1: trying loader of application "flaskpackagename"
       class: jinja2.loaders.FileSystemLoader
       encoding: 'utf-8'
       followlinks: False
       searchpath:
         - /.../project/flaskpackagename/templates
       -> found ('/.../project/flaskpackagename/templates/foo/bar.html')
[2019-06-15 16:03:39,203] INFO in debughelpers: Locating template "base.html":
    1: trying loader of application "flaskpackagename"
       class: jinja2.loaders.FileSystemLoader
       encoding: 'utf-8'
       followlinks: False
       searchpath:
         - /.../project/flaskpackagename/templates
       -> found ('/.../project/flaskpackagename/templates/base.html')

Blaupausen können auch ihre eigenen Vorlagenverzeichnisse registrieren. Dies ist jedoch nicht erforderlich, wenn Sie Blaupausen verwenden, um die Aufteilung eines größeren Projekts auf logische Einheiten zu vereinfachen. Das Hauptvorlagenverzeichnis der Flask-App wird immer zuerst durchsucht, auch wenn zusätzliche Pfade pro Blaupause verwendet werden.

Martijn Pieters
quelle
2
EXPLAIN_TEMPLATE_LOADING ist sehr nützlich, um Pfadprobleme in Bezug auf Vorlagen zu debuggen. Wenn Sie Blaupausen verwenden, stellen Sie außerdem sicher, dass Sie den template_folderPfad pro Blaupause festlegen .
Justin Krause
1
@ JustinKrause: Danke für die, EXPLAIN_TEMPLATE_LOADINGwurde hinzugefügt, nachdem diese Antwort ursprünglich geschrieben wurde.
Martijn Pieters
1
Scheint, als ob meine lokale Flasche (unter Windows) darin Vorlagen finden kann ./Templates/index.html, aber wenn ich sie auf Heroku bereitstelle (dachte, es wäre dasselbe Python, dieselben Bibliotheksversionen, einschließlich derselben Flaschenversion; aber Heroku ist Unix); und wirft TemplateNotFoundFehler; Nachdem ich den Ordner umbenannt hatte git mv Templates/index.html templates/index.html, funktionierten sowohl lokale (Windows) als auch Heroku (Unix) Versionen
The Red Pea
1
@TheRedPea ja, weil das Windows-Dateisystem Groß- und Kleinschreibung so faltet Templates== templates. Aber Heroku läuft unter Linux mit einem Dateisystem, bei dem zwischen Groß- und Kleinschreibung unterschieden wird.
Martijn Pieters
11

Ich denke, Flask verwendet standardmäßig die Verzeichnisvorlagen. Ihr Code sollte also annehmen, dass dies Ihre hello.py ist

from flask import Flask,render_template

app=Flask(__name__,template_folder='template')


@app.route("/")
def home():
    return render_template('home.html')

@app.route("/about/")
def about():
    return render_template('about.html')

if __name__=="__main__":
    app.run(debug=True)

Und Sie arbeiten wie Raumstruktur

project/
    hello.py        
    template/
         home.html
         about.html    
    static/
           js/
             main.js
           css/
               main.css

Außerdem haben Sie zwei HTML-Dateien mit dem Namen home.html und about.html erstellt und diese Dateien im Vorlagenordner abgelegt.

Akshay Karande
quelle
8

(Bitte beachten Sie, dass die oben akzeptierte Antwort für die Datei- / Projektstruktur absolut korrekt ist.)

Ebenfalls..

Zusätzlich zum ordnungsgemäßen Einrichten der Projektdateistruktur müssen wir flask anweisen, in der entsprechenden Ebene der Verzeichnishierarchie nachzuschauen.

beispielsweise..

    app = Flask(__name__, template_folder='../templates')
    app = Flask(__name__, template_folder='../templates', static_folder='../static')

Beginnen mit ../Verschiebt ein Verzeichnis rückwärts und beginnt dort.

Beginnend mit ../../bewegt sich zwei Verzeichnisse rückwärts und beginnt dort (und so weiter ...).

Hoffe das hilft

Niemand
quelle
4

Ich weiß nicht warum, aber ich musste stattdessen die folgende Ordnerstruktur verwenden. Ich habe "Vorlagen" eine Ebene höher gestellt.

project/
    app/
        hello.py
        static/
            main.css
    templates/
        home.html
    venv/

Dies deutet wahrscheinlich auf eine Fehlkonfiguration an anderer Stelle hin, aber ich konnte nicht herausfinden, was das war, und dies funktionierte.

François Breton
quelle
3

Prüfe das:

  1. Die Vorlagendatei hat den richtigen Namen
  2. Die Vorlagendatei befindet sich in einem Unterverzeichnis namens templates
  3. Der Name, an den Sie übergeben, bezieht sich render_templateauf das Vorlagenverzeichnis ( index.htmlbefindet sich direkt im Vorlagenverzeichnis, auth/login.htmlbefindet sich unter dem Auth-Verzeichnis im Vorlagenverzeichnis.)
  4. Sie haben entweder kein Unterverzeichnis mit demselben Namen wie Ihre App oder das Vorlagenverzeichnis befindet sich in diesem Unterverzeichnis.

Wenn dies nicht funktioniert, aktivieren Sie debugging ( app.debug = True), um herauszufinden, was falsch ist.

Eric
quelle
2

Wenn die Funktion render_template () verwendet wird, wird versucht, im Ordner templates nach einer Vorlage zu suchen, und es wird der Fehler jinja2.exceptions.TemplateNotFound ausgelöst, wenn:

  1. Die HTML-Datei existiert nicht oder
  2. wenn Vorlagenordner nicht vorhanden sind

Um das Problem zu lösen :

Erstellen Sie einen Ordner mit Namensvorlagen in demselben Verzeichnis, in dem sich die Python-Datei befindet, und legen Sie die erstellte HTML-Datei im Vorlagenordner ab.

Atal Kumar
quelle
2

Wenn Sie Ihren Code von einem installierten Paket aus ausführen, stellen Sie sicher, dass Vorlagendateien im Verzeichnis vorhanden sind <python root>/lib/site-packages/your-package/templates.


Ein paar Details:

In meinem Fall habe ich versucht, Beispiele für das Projekt flask_simple_ui auszuführen und jinjawürde immer sagen

jinja2.exceptions.TemplateNotFound: form.html

Der Trick war, dass das Beispielprogramm das installierte Paket importieren würde flask_simple_ui. Und ninjaaus verwendet wird innerhalb dieses Pakets als Stammverzeichnis wird mit dem Paketpfad für die Suche, in meinem Fall ...python/lib/site-packages/flask_simple_ui, stattos.getcwd() als man erwarten würde.

Zu meinem Pech setup.pyhat ein Fehler und kopiert keine HTML-Dateien, einschließlich der fehlenden form.html. Nachdem ich setup.pydas Problem behoben hatte , verschwand das Problem mit TemplateNotFound .

Ich hoffe es hilft jemandem.

Yuriy Pozniak
quelle
1

Sie müssen alle Ihre .htmlDateien im Vorlagenordner neben Ihrem Python-Modul ablegen. Und wenn es Bilder gibt, die Sie in Ihren HTML-Dateien verwenden, müssen Sie alle Ihre Dateien in den Ordner mit dem Namen static legen

In der folgenden Struktur

project/
    hello.py
    static/
        image.jpg
        style.css
    templates/
        homepage.html
    virtual/
        filename.json
Madhusudan Chowdary
quelle
1

Ich hatte den gleichen Fehler. Das einzige, was ich falsch gemacht habe, war, meinen Ordner "Vorlagen" "Vorlage" ohne "s" zu nennen. Nachdem ich geändert habe, dass es gut funktioniert hat, weiß ich nicht, warum es eine Sache ist, aber es ist.

Shubham Khaire
quelle
1

Eine andere Alternative besteht darin, root_pathdie festzulegen, mit der das Problem sowohl für Vorlagen als auch für statische Ordner behoben wird.

root_path = Path(sys.executable).parent if getattr(sys, 'frozen', False) else Path(__file__).parent
app = Flask(__name__.split('.')[0], root_path=root_path)

Wenn Sie Vorlagen direkt über rendern Jinja2, schreiben Sie:

ENV = jinja2.Environment(loader=jinja2.FileSystemLoader(str(root_path / 'templates')))
template = ENV.get_template(your_template_name)
Max
quelle