El matraz genera el error TemplateNotFound aunque existe un archivo de plantilla

108

Estoy intentando renderizar el archivo home.html. El archivo existe en mi proyecto, pero sigo recibiendo jinja2.exceptions.TemplateNotFound: home.htmlcuando trato de renderizarlo. ¿Por qué Flask no puede encontrar mi plantilla?

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
fuente

Respuestas:

213

Debe crear sus archivos de plantilla en la ubicación correcta; en el templatessubdirectorio junto a su módulo de Python.

El error indica que no hay ningún home.htmlarchivo en el templates/directorio. Asegúrese de haber creado ese directorio en el mismo directorio que su módulo de Python, y de haber puesto un home.htmlarchivo en ese subdirectorio. Si su aplicación es un paquete, la carpeta de plantillas debe crearse dentro del paquete.

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

Alternativamente, si nombró a su carpeta de plantillas de otro modo templatesy no desea cambiarle el nombre predeterminado, puede decirle a Flask que use ese otro directorio.

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

Puede pedirle a Flask que le explique cómo intentó encontrar una plantilla determinada, estableciendo la EXPLAIN_TEMPLATE_LOADINGopción en True. Por cada plantilla cargada, obtendrá un informe registrado en el matrazapp.logger , a nivel INFO.

Así es como se ve cuando una búsqueda tiene éxito; en este ejemplo, la foo/bar.htmlplantilla amplía la base.htmlplantilla, por lo que hay dos búsquedas:

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

Los blueprints también pueden registrar sus propios directorios de plantillas , pero esto no es un requisito si está utilizando blueprints para facilitar la división de un proyecto más grande en unidades lógicas. El directorio principal de plantillas de la aplicación Flask siempre se busca primero incluso cuando se utilizan rutas adicionales por plano.

Martijn Pieters
fuente
2
EXPLAIN_TEMPLATE_LOADING es muy útil para depurar problemas de ruta alrededor de plantillas. Además, si usa Blueprints, asegúrese de establecer la template_folderruta por blueprint .
Justin Krause
1
@JustinKrause: gracias por esos, EXPLAIN_TEMPLATE_LOADINGse agregó después de que esta respuesta se escribió inicialmente.
Martijn Pieters
1
Parece que mi matraz local (en Windows) puede encontrar plantillas dentro ./Templates/index.html, pero cuando lo implemento en heroku (pensé que era el mismo Python, las mismas versiones de biblioteca, incluida la misma versión de Flask; pero heroku es Unix); y arroja TemplateNotFounderror; después de cambiar el nombre de la carpeta git mv Templates/index.html templates/index.html, las versiones local (Windows) y heroku (Unix) funcionaron
The Red Pea
1
@TheRedPea sí, porque el sistema de archivos de Windows pliega el caso así Templates== templates. Pero Heroku ejecuta Linux, con un sistema de archivos sensible a mayúsculas y minúsculas.
Martijn Pieters
11

Creo que Flask usa las plantillas de directorio por defecto. Entonces su código debería ser suponer que este es su 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)

Y trabajas la estructura del espacio como

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

también ha creado dos archivos html con el nombre de home.html y about.html y los ha puesto en la carpeta de plantillas.

Akshay Karande
fuente
8

(Tenga en cuenta que la respuesta aceptada anteriormente proporcionada para la estructura del archivo / proyecto es absolutamente correcta).

También..

Además de configurar correctamente la estructura de archivos del proyecto, tenemos que decirle a flask que busque en el nivel apropiado de la jerarquía de directorios.

por ejemplo..

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

Comenzar con ../mueve un directorio hacia atrás y comienza allí.

Comenzar con ../../mueve dos directorios hacia atrás y comienza allí (y así sucesivamente ...).

Espero que esto ayude

Ninguno
fuente
4

No sé por qué, pero tuve que usar la siguiente estructura de carpetas. Pongo "plantillas" un nivel arriba.

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

Esto probablemente indica una mala configuración en otro lugar, pero no pude averiguar qué era y funcionó.

François Breton
fuente
3

Mira esto:

  1. el archivo de plantilla tiene el nombre correcto
  2. el archivo de plantilla está en un subdirectorio llamado templates
  3. el nombre al que pasa render_templatees relativo al directorio de plantillas ( index.htmlestaría directamente en el directorio de plantillas, auth/login.htmlestaría bajo el directorio de autenticación en el directorio de plantillas).
  4. o no tiene un subdirectorio con el mismo nombre que su aplicación, o el directorio de plantillas está dentro de ese subdirectorio.

Si eso no funciona, active la depuración ( app.debug = True) que podría ayudar a descubrir qué está mal.

Eric
fuente
3

Si ejecuta su código desde un paquete instalado, asegúrese de que los archivos de plantilla estén presentes en el directorio <python root>/lib/site-packages/your-package/templates.


Algunos detalles:

En mi caso, estaba tratando de ejecutar ejemplos del proyecto flask_simple_ui y jinjasiempre decía

jinja2.exceptions.TemplateNotFound: form.html

El truco era que el programa de muestra importaría el paquete instalado flask_simple_ui. Y ninjase usa desde el interior de ese paquete como directorio raíz para buscar la ruta del paquete, en mi caso ...python/lib/site-packages/flask_simple_ui, en lugar de os.getcwd() lo que cabría esperar.

Para mi mala suerte, setup.pytiene un error y no copia ningún archivo html, incluido el que falta form.html. Una vez que lo solucioné setup.py, el problema con TemplateNotFound desapareció.

Espero que esto ayude a alguien.

Yuriy Pozniak
fuente
2

Tuve el mismo error y resultó que lo único que hice mal fue nombrar mi carpeta 'plantillas', 'plantilla' sin 's'. Después de cambiar que funcionó bien, no sé por qué es una cosa, pero lo es.

Shubham Khaire
fuente
2

Cuando se usa la función render_template (), intenta buscar una plantilla en la carpeta llamada templates y arroja el error jinja2.exceptions.TemplateNotFound cuando:

  1. el archivo html no existe o
  2. cuando la carpeta de plantillas no existe

Para resolver el problema :

cree una carpeta con plantillas de nombres en el mismo directorio donde se encuentra el archivo python y coloque el archivo html creado en la carpeta de plantillas.

Atal Kumar
fuente
1

Debe colocar todos sus .htmlarchivos en la carpeta de plantillas junto a su módulo de Python. Y si hay imágenes que está utilizando en sus archivos html, entonces debe poner todos sus archivos en la carpeta llamada static

En la siguiente estructura

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

Otra alternativa es configurar el root_pathque soluciona el problema tanto para las plantillas como para las carpetas estáticas.

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 renderiza plantillas directamente a través de Jinja2, entonces escribe:

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