Flask выдает ошибку TemplateNotFound, даже если файл шаблона существует

#python #flask

#python #файл #шаблоны #flask

Вопрос:

Я пытаюсь отобразить файл home.html . Файл существует в моем проекте, но я продолжаю получать jinja2.exceptions.TemplateNotFound: home.html , когда пытаюсь его отобразить. Почему Flask не может найти мой шаблон?

 from flask import Flask, render_template

app = Flask(__name__)

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

Ответ №1:

Вы должны создать свои файлы шаблонов в правильном месте; в templates подкаталоге рядом с модулем python (== модуль, в котором вы создаете свое приложение Flask).

Ошибка указывает на то, что в home.html каталоге нет templates/ файла. Убедитесь, что вы создали этот каталог в том же каталоге, что и ваш модуль python, и что вы действительно поместили home.html файл в этот подкаталог. Если ваше приложение является пакетом, папка templates должна быть создана внутри пакета.

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

В качестве альтернативы, если вы назвали свою папку templates как-то иначе, чем templates и не хотите переименовывать ее по умолчанию, вы можете указать Flask использовать этот другой каталог.

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

Вы можете попросить Flask объяснить, как он пытался найти данный шаблон, установив для EXPLAIN_TEMPLATE_LOADING параметра значение True . Для каждого загруженного шаблона вы получите отчет, зарегистрированный в Flask app.logger на уровне INFO .

Вот как это выглядит при успешном поиске; в этом примере foo/bar.html шаблон расширяет base.html шаблон, поэтому выполняется два поиска:

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

Чертежи также могут регистрировать свои собственные каталоги шаблонов, но это не является обязательным требованием, если вы используете чертежи, чтобы упростить разделение более крупного проекта по логическим блокам. Поиск в главном каталоге шаблонов приложения Flask всегда выполняется первым, даже при использовании дополнительных путей для каждой схемы элементов.

Комментарии:

1. Похоже, что мой локальный flask (в Windows) может находить шаблоны внутри ./Templates/index.html , но при развертывании в heroku (думал, что это тот же Python, те же версии библиотек, включая ту же версию Flask; но heroku — Unix); и выдает TemplateNotFound ошибку; после того, как я переименовал папку git mv Templates/index.html templates/index.html , работали как локальные (Windows), так и heroku (Unix) версии

2. @TheRedPea да, потому что файловая система Windows таким образом сворачивает регистр Templates == templates . Но Heroku работает под управлением Linux с чувствительной к регистру файловой системой.

Ответ №2:

Я думаю, что Flask использует каталог template по умолчанию. Итак, ваш код должен быть таким

предположим, что это ваш 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)
  

И вы работаете со структурой пространства, подобной

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

также вам нужно создать два html-файла с именем home.html и about.html и поместить эти файлы в templates папку.

Комментарии:

1. Было совершенно неожиданно, что по умолчанию используется папка с именем templates. исправлено для меня, придется опасаться бесполезных значений по умолчанию.

2. имя папки ‘templates’, а не ‘template’.

Ответ №3:

Если вам необходимо использовать настроенную структуру каталогов проекта (отличную от принятой структуры проекта ответов), у нас есть возможность указать flask искать на соответствующем уровне иерархии каталогов.

например..

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

Начиная с ../ перемещает один каталог назад и начинается там.

Начиная с ../../ перемещает два каталога назад и начинается там (и так далее …).

В подкаталоге…

 template_folder='templates/some_template'
  

Ответ №4:

Я не знаю почему, но вместо этого мне пришлось использовать следующую структуру папок. Я поднял «шаблоны» на один уровень выше.

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

Вероятно, это указывает на неправильную конфигурацию в другом месте, но я не смог выяснить, что это было, и это сработало.

Комментарии:

1. Вы уверены, что у вас есть app = Flask(__name__) ?

2. Я также не вижу __init__.py файла внутри app/ .

Ответ №5:

Если вы запускаете свой код из установленного пакета, убедитесь, что файлы шаблонов присутствуют в каталоге <python root>/lib/site-packages/your-package/templates .


Некоторые подробности:

В моем случае я пытался запустить примеры проекта flask_simple_ui и jinja всегда говорил

jinja2.исключения.TemplateNotFound: form.html

Хитрость заключалась в том, что примерная программа импортировала установленный пакет flask_simple_ui . И ninja используется изнутри этого пакета, используя в качестве корневого каталога для поиска пути к пакету, в моем случае ...python/lib/site-packages/flask_simple_ui , вместо os.getcwd() того, что можно было бы ожидать.

К моему неудаче, setup.py имеет ошибку и не копирует никакие HTML-файлы, включая отсутствующие form.html . Как только я исправил setup.py , проблема с TemplateNotFound исчезла.

Я надеюсь, что это кому-то поможет.

Ответ №6:

Проверьте, что:

  1. файл шаблона имеет правильное имя
  2. файл шаблона находится в подкаталоге под названием templates
  3. имя, которое вы передаете, render_template относится к каталогу шаблонов ( index.html было бы непосредственно в каталоге templates, auth/login.html было бы в каталоге auth в каталоге templates.)
  4. у вас либо нет подкаталога с тем же именем, что и у вашего приложения, либо каталог templates находится внутри этого подкаталога.

Если это не сработает, включите debugging ( app.debug = True ), которая может помочь выяснить, что не так.

Ответ №7:

У меня была такая же ошибка, оказывается, единственное, что я сделал неправильно, это назвал мою папку «templates» «template» без «s». После изменения этого он работал нормально, не знаю, почему это так, но это так.

Ответ №8:

Вам нужно поместить все ваши .html файлы в папку template рядом с вашим модулем python. И если в ваших HTML-файлах есть какие-либо изображения, которые вы используете, тогда вам нужно поместить все ваши файлы в папку с именем static

В следующей структуре

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

Ответ №9:

При использовании функции render_template() она пытается выполнить поиск шаблона в папке с именем templates и выдает ошибку jinja2.exceptions.TemplateNotFound, когда :

  1. файл не существует или
  2. папка templates не существует

Создайте папку с именем templates в том же каталоге, где находится файл python, и поместите созданный HTML-файл в папку templates.

Ответ №10:

Другой альтернативой является установка root_path , которая устраняет проблему как для шаблонов, так и для статических папок.

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

Если вы визуализируете шаблоны напрямую через Jinja2 , то вы пишете:

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

Ответ №11:

После долгой работы я получил решение только из этого поста, ссылка на сообщение о решении

Добавьте полный путь к параметру template_folder

 app = Flask(__name__,
        template_folder='/home/project/templates/'
        )
  

Ответ №12:

Мое решение для того, кто установил имя приложения flask

 from flask import Flask, render_template

app = Flask('MATH') # <---- the name should be different from project folder name. For example uppercase

@app.route('/')
  

Очень важно, чтобы имя экземпляра flask отличалось от имени каталога проекта. Например, ‘math1’ или ‘Math’ или ‘МАТЕМАТИКА’

дерево проекта:

 /math/
  app.py
  templates/
    hello.html
  

Ответ №13:

Моя проблема заключалась в том, что файл, на который я ссылался изнутри моего, home.html был .j2 вместо .html , и когда я изменил его обратно, джинджа смог его прочитать.

Глупая ошибка, но это может кому-то помочь.

Ответ №14:

Моя ошибка была глупой. Я вставил templates в pass, вот так:

     return render_template('./templates/index.html')
  

ОДНАКО вам просто нужно передать передачу относительно templates каталога, то есть:

     return render_template('./index.html')
  

Ответ №15:

если кто-либо впервые запускает ваш код на python, и если вы создаете html-файл и файл python в одном каталоге верхнего уровня app = Flask(__name__, template_folder='') , это сработает

Ответ №16:

Другое объяснение, которое я выяснил для себя, когда вы создаете приложение Flask, папка, в templates которой выполняется поиск, — это папка приложения в соответствии с именем, которое вы предоставили конструктору Flask:

 app = Flask(__name__)
  

__name__ Здесь указано имя модуля, в котором запущено приложение. Таким образом, соответствующая папка станет корневой для поиска папок.

 projects/
    yourproject/
        app/
            templates/
  

Поэтому, если вы укажете вместо этого какое-нибудь случайное имя, корневой папкой для поиска будет текущая папка.