Flask memunculkan kesalahan TemplateNotFound meskipun file template ada

111

Saya mencoba membuat file home.html. File tersebut ada dalam proyek saya, tetapi saya terus mendapatkannya jinja2.exceptions.TemplateNotFound: home.htmlsaat mencoba merendernya. Mengapa Flask tidak dapat menemukan template saya?

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
sumber

Jawaban:

221

Anda harus membuat file template Anda di lokasi yang benar; di templatessubdirektori di sebelah modul python Anda.

Kesalahan menunjukkan bahwa tidak ada home.htmlfile di templates/direktori. Pastikan Anda membuat direktori itu di direktori yang sama dengan modul python Anda, dan bahwa Anda memang meletakkan home.htmlfile di subdirektori itu. Jika aplikasi Anda adalah sebuah paket, folder template harus dibuat di dalam paket tersebut.

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

Alternatifnya, jika Anda menamai folder templat Anda dengan nama lain templatesdan tidak ingin menamainya kembali ke default, Anda dapat memberi tahu Flask untuk menggunakan direktori lain itu.

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

Anda dapat meminta Flask untuk menjelaskan bagaimana ia mencoba menemukan template yang diberikan, dengan menyetel EXPLAIN_TEMPLATE_LOADINGopsi ke True. Untuk setiap template yang dimuat, Anda akan mendapatkan laporan yang dicatat ke Flaskapp.logger , di level INFO.

Inilah yang terlihat ketika pencarian berhasil; dalam contoh ini foo/bar.htmltemplate memperluas base.htmltemplate, jadi ada dua pencarian:

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

Cetak biru juga dapat mendaftarkan direktori templatnya sendiri , tetapi ini bukan persyaratan jika Anda menggunakan cetak biru agar lebih mudah membagi proyek yang lebih besar ke seluruh unit logis. Direktori template aplikasi Flask utama selalu dicari terlebih dahulu bahkan saat menggunakan jalur tambahan per cetak biru.

Martijn Pieters
sumber
2
EXPLAIN_TEMPLATE_LOADING sangat berguna untuk men-debug masalah jalur di sekitar template. Selain itu, jika Anda menggunakan Blueprints, pastikan Anda mengatur template_folderjalur per cetak biru .
Justin Krause
1
@JustinKrause: terima kasih untuk itu, EXPLAIN_TEMPLATE_LOADINGditambahkan setelah jawaban ini awalnya ditulis.
Martijn Pieters
2
Sepertinya flask lokal saya (pada Windows) dapat menemukan template di dalamnya ./Templates/index.html, tetapi ketika saya menyebarkan ke heroku (mengira itu adalah Python yang sama, versi pustaka yang sama, termasuk versi Flask yang sama; tetapi heroku adalah Unix); dan melempar TemplateNotFoundkesalahan; setelah saya mengganti nama folder git mv Templates/index.html templates/index.html, versi lokal (Windows) dan heroku (Unix) berfungsi
The Red Pea
1
@TheRedPea ya, karena filesystem Windows melipat case jadi Templates== templates. Tapi Heroku menjalankan Linux, dengan filesystem case sensitive.
Martijn Pieters
13

Saya rasa Flask menggunakan template direktori secara default. Jadi kode Anda haruslah misalkan ini adalah hello.py Anda

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)

Dan Anda menyukai struktur ruang

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

Anda juga telah membuat dua file html dengan nama home.html dan about.html dan meletakkan file tersebut di folder template.

Akshay Karande
sumber
8

(Harap dicatat bahwa Jawaban yang diterima di atas diberikan untuk file / struktur proyek benar-benar benar.)

Juga..

Sebagai tambahan untuk mengatur struktur file proyek dengan benar, kita harus memberi tahu flask untuk melihat level hirarki direktori yang sesuai.

sebagai contoh..

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

Dimulai dengan ../memindahkan satu direktori ke belakang dan mulai dari sana.

Dimulai dengan ../../memindahkan dua direktori ke belakang dan mulai dari sana (dan seterusnya ...).

Semoga ini membantu

Tidak ada
sumber
5

Saya tidak tahu mengapa, tetapi saya harus menggunakan struktur folder berikut sebagai gantinya. Saya menempatkan "template" satu tingkat ke atas.

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

Ini mungkin menunjukkan kesalahan konfigurasi di tempat lain, tetapi saya tidak tahu apa itu dan ini berhasil.

François Breton
sumber
3

Periksa itu:

  1. file template memiliki nama yang benar
  2. file template dalam subdirektori bernama templates
  3. nama yang Anda berikan render_templateadalah relatif terhadap direktori template ( index.htmlakan langsung berada di direktori templates, auth/login.htmlakan berada di bawah direktori auth di direktori templates.)
  4. Anda juga tidak memiliki subdirektori dengan nama yang sama dengan aplikasi Anda, atau direktori template ada di dalam subdir tersebut.

Jika tidak berhasil, aktifkan debugging ( app.debug = True) yang mungkin membantu mencari tahu apa yang salah.

Eric
sumber
3

Jika Anda menjalankan kode Anda dari paket yang diinstal, pastikan file template ada di direktori <python root>/lib/site-packages/your-package/templates.


Beberapa detail:

Dalam kasus saya, saya mencoba menjalankan contoh proyek flask_simple_ui dan jinjaakan selalu berkata

jinja2.exceptions.TemplateNotFound: form.html

Triknya adalah program sampel akan mengimpor paket yang diinstal flask_simple_ui. Dan ninjadigunakan dari dalam paket itu digunakan sebagai direktori root untuk mencari jalur paket, dalam kasus saya ...python/lib/site-packages/flask_simple_ui, bukan os.getcwd() seperti yang diharapkan.

Sayangnya, saya setup.pymemiliki bug dan tidak menyalin file html apa pun, termasuk yang hilang form.html. Setelah saya perbaiki setup.py, masalah dengan TemplateNotFound lenyap.

Saya harap ini membantu seseorang.

Yuriy Pozniak
sumber
2

Saya mengalami kesalahan yang sama ternyata satu-satunya hal yang saya lakukan salah adalah memberi nama folder 'template' saya, 'template' tanpa 's'. Setelah mengubahnya itu berfungsi dengan baik, tidak tahu mengapa itu adalah sesuatu tetapi itu benar.

Shubham Khaire
sumber
2

Ketika fungsi render_template () digunakan, ia mencoba mencari template di folder yang disebut template dan memunculkan error jinja2.exceptions.TemplateNotFound ketika:

  1. file html tidak ada atau
  2. ketika folder template tidak ada

Untuk memecahkan masalah :

buat folder dengan template nama di direktori yang sama tempat file python berada dan letakkan file html yang dibuat di folder template.

Atal Kumar
sumber
1

Anda harus meletakkan semua .htmlfile Anda di folder template di sebelah modul python Anda. Dan jika ada gambar yang Anda gunakan di file html Anda maka Anda perlu meletakkan semua file Anda di folder bernama statis

Dalam Struktur berikut

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

Alternatif lain adalah mengatur root_pathmana yang memperbaiki masalah baik untuk templat maupun folder statis.

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

Jika Anda merender template secara langsung melalui Jinja2, maka Anda menulis:

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

Masalah saya adalah bahwa file yang saya rujuk dari dalam saya home.htmladalah .j2bukan sebuah .html, dan ketika saya mengubahnya kembali jinja bisa membacanya.

Kesalahan bodoh tetapi mungkin membantu seseorang.

Masih belajar
sumber