Flask génère une erreur TemplateNotFound même si le fichier de modèle existe

108

J'essaye de rendre le fichier home.html. Le fichier existe dans mon projet, mais je reçois jinja2.exceptions.TemplateNotFound: home.htmlquand j'essaye de le rendre. Pourquoi Flask ne trouve-t-il pas mon modèle?

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
la source

Réponses:

213

Vous devez créer vos fichiers de modèle à l'emplacement correct; dans le templatessous - répertoire à côté de votre module python.

L'erreur indique qu'il n'y a pas de home.htmlfichier dans le templates/répertoire. Assurez-vous que vous avez créé ce répertoire dans le même répertoire que votre module python, et que vous avez en fait placé un home.htmlfichier dans ce sous-répertoire. Si votre application est un package, le dossier des modèles doit être créé à l' intérieur du package.

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

Sinon, si vous avez nommé votre dossier de modèles autrement que templateset que vous ne souhaitez pas le renommer par défaut, vous pouvez indiquer à Flask d'utiliser cet autre répertoire.

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

Vous pouvez demander à Flask d'expliquer comment il a essayé de trouver un modèle donné, en définissant l' EXPLAIN_TEMPLATE_LOADINGoption sur True. Pour chaque modèle chargé, vous obtiendrez un rapport enregistré dans le Flaskapp.logger , au niveau INFO.

Voici à quoi cela ressemble lorsqu'une recherche est réussie; dans cet exemple, le foo/bar.htmlmodèle étend le base.htmlmodèle, il y a donc deux recherches:

[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')

Les Blueprints peuvent également enregistrer leurs propres répertoires de modèles , mais ce n'est pas obligatoire si vous utilisez des Blueprints pour faciliter la division d'un projet plus important en unités logiques. Le répertoire principal du modèle d'application Flask est toujours recherché en premier, même lorsque vous utilisez des chemins supplémentaires par plan.

Martijn Pieters
la source
2
EXPLAIN_TEMPLATE_LOADING est très utile pour déboguer les problèmes de chemin autour des modèles. De plus, si vous utilisez des Blueprints, assurez-vous de définir le template_folderchemin par Blueprint .
Justin Krause le
1
@JustinKrause: merci pour ceux-ci, a EXPLAIN_TEMPLATE_LOADINGété ajouté après que cette réponse ait été initialement écrite.
Martijn Pieters
1
On dirait que mon flask local (sur Windows) peut trouver des modèles à l'intérieur ./Templates/index.html, mais quand je déploie sur heroku (je pensais que c'était le même Python, les mêmes versions de bibliothèque, y compris la même version de Flask; mais heroku est Unix); et jette une TemplateNotFounderreur; après avoir renommé le dossier git mv Templates/index.html templates/index.html, les versions locale (Windows) et heroku (Unix) ont fonctionné
The Red Pea
1
@TheRedPea oui, car le système de fichiers Windows replie la casse donc Templates== templates. Mais Heroku exécute Linux, avec un système de fichiers sensible à la casse.
Martijn Pieters
11

Je pense que Flask utilise les modèles de répertoire par défaut. Donc, votre code devrait être supposé que c'est votre hello.py

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)

Et vous travaillez la structure de l'espace comme

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

vous devez également créer deux fichiers html avec le nom de home.html et about.html et mettre ces fichiers dans le dossier de modèle.

Akshay Karande
la source
8

(Veuillez noter que la réponse acceptée ci-dessus fournie pour la structure du fichier / projet est absolument correcte.)

Aussi..

En plus de configurer correctement la structure des fichiers du projet, nous devons dire à flask de chercher au niveau approprié de la hiérarchie des répertoires.

par exemple..

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

Commencer par ../déplace un répertoire vers l'arrière et commence là.

Commencer par ../../déplace deux répertoires vers l'arrière et commence là (et ainsi de suite ...).

J'espère que cela t'aides

Personne
la source
4

Je ne sais pas pourquoi, mais j'ai dû utiliser la structure de dossiers suivante à la place. J'ai mis des "modèles" d'un niveau plus haut.

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

Cela indique probablement une mauvaise configuration ailleurs, mais je ne pouvais pas comprendre ce que c'était et cela fonctionnait.

François Breton
la source
3

Regarde ça:

  1. le fichier modèle a le bon nom
  2. le fichier modèle se trouve dans un sous-répertoire appelé templates
  3. le nom que vous passez render_templateest relatif au répertoire des modèles ( index.htmlserait directement dans le répertoire des modèles, auth/login.htmlserait sous le répertoire auth dans le répertoire des modèles.)
  4. soit vous n'avez pas de sous-répertoire avec le même nom que votre application, soit le répertoire des modèles se trouve à l'intérieur de ce sous-répertoire.

Si cela ne fonctionne pas, activez le débogage ( app.debug = True) qui peut vous aider à comprendre ce qui ne va pas.

Eric
la source
3

Si vous exécutez votre code à partir d'un package installé, assurez-vous que les fichiers de modèle sont présents dans le répertoire <python root>/lib/site-packages/your-package/templates.


Quelques détails:

Dans mon cas, j'essayais d'exécuter des exemples de projet flask_simple_ui et jinjaje disais toujours

jinja2.exceptions.TemplateNotFound: form.html

L'astuce était que l'exemple de programme importait le package installé flask_simple_ui. Et ninjaêtre utilisé à l'intérieur de ce package utilise comme répertoire racine pour rechercher le chemin du package, dans mon cas...python/lib/site-packages/flask_simple_ui , au lieu deos.getcwd() ce à quoi on pourrait s'attendre.

À ma malchance, setup.pya un bogue et ne copie aucun fichier html, y compris les fichiers manquants form.html. Une fois que j'ai résolu setup.py, le problème avec TemplateNotFound disparu.

J'espère que cela aide quelqu'un.

Yuriy Pozniak
la source
2

J'ai eu la même erreur, mais la seule chose que j'ai mal faite a été de nommer mon dossier «templates», «template» sans «s». Après avoir changé cela, cela fonctionnait bien, je ne sais pas pourquoi c'est une chose mais c'est le cas.

Shubham Khaire
la source
2

Lorsque la fonction render_template () est utilisée, elle essaie de rechercher un modèle dans le dossier appelé templates et renvoie l'erreur jinja2.exceptions.TemplateNotFound lorsque:

  1. le fichier html n'existe pas ou
  2. lorsque le dossier de modèles n’existe pas

Résoudre le problème :

créez un dossier avec des modèles de nom dans le même répertoire où se trouve le fichier python et placez le fichier html créé dans le dossier des modèles.

Atal Kumar
la source
1

Vous devez placer tous vos .htmlfichiers dans le dossier de modèles à côté de votre module python. Et s'il y a des images que vous utilisez dans vos fichiers html, vous devez placer tous vos fichiers dans le dossier nommé static

Dans la structure suivante

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

Une autre alternative consiste à définir le root_pathqui résout le problème à la fois pour les modèles et les dossiers statiques.

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

Si vous effectuez le rendu des modèles directement via Jinja2, vous écrivez:

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