Flask, şablon dosyası mevcut olmasına rağmen TemplateNotFound hatası veriyor


111

Dosyayı oluşturmaya çalışıyorum home.html. Dosya projemde var, ancak onu jinja2.exceptions.TemplateNotFound: home.htmloluşturmaya çalıştığımda almaya devam ediyorum. Flask şablonumu neden bulamıyor?

from flask import Flask, render_template

app = Flask(__name__)

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

Yanıtlar:


221

Şablon dosyalarınızı doğru konumda oluşturmanız gerekir; içinde templatesalt dizine yanında piton modülüne.

Hata home.html, templates/dizinde dosya olmadığını gösterir . Bu dizini python modülünüzle aynı dizinde oluşturduğunuzdan ve aslında home.htmlbu alt dizine bir dosya koyduğunuzdan emin olun . Uygulamanız bir paketse, şablonlar klasörü paketin içinde oluşturulmalıdır .

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

Alternatif olarak, şablonlar klasörünüze başka bir ad verdiyseniz templatesve varsayılana yeniden adlandırmak istemiyorsanız, Flask'a o diğer dizini kullanmasını söyleyebilirsiniz.

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

EXPLAIN_TEMPLATE_LOADINGSeçeneği olarak ayarlayarak Flask'tan belirli bir şablonu nasıl bulmaya çalıştığını açıklamasını isteyebilirsiniz True. Yüklenen her şablon için, Flask'aapp.logger seviye olarak kaydedilmiş bir rapor alacaksınız INFO.

Bir arama başarılı olduğunda böyle görünür; bu örnekte foo/bar.htmlşablon şablonu genişletir base.html, bu nedenle iki arama vardır:

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

Taslaklar kendi şablon dizinlerini de kaydedebilir , ancak daha büyük bir projeyi mantıksal birimler arasında bölmeyi kolaylaştırmak için planları kullanıyorsanız bu bir gereklilik değildir. Ana Flask uygulaması şablon dizini, plan başına ek yollar kullanıldığında bile her zaman ilk olarak aranır.


2
EXPLAIN_TEMPLATE_LOADING , şablonlardaki yol sorunlarını ayıklamak için çok yararlıdır. Ayrıca Taslaklar kullanıyorsanız, plan başınatemplate_folder yolu ayarladığınızdan emin olun .
Justin Krause

1
@JustinKrause: Bunlar için teşekkürler EXPLAIN_TEMPLATE_LOADING, başlangıçta bu cevap yazıldıktan sonra eklendi.
Martijn Pieters

2
Görünüşe göre yerel ./Templates/index.htmlşişem ( Windows'ta) içinde şablonları bulabilir , ancak heroku'ya konuşlandırdığımda (aynı Python olduğunu düşündüm, aynı Flask sürümü dahil aynı kitaplık sürümleri; ancak heroku Unix'tir); ve TemplateNotFoundhata atar ; Klasörü yeniden adlandırdıktan sonra git mv Templates/index.html templates/index.htmlhem yerel (Windows) hem de heroku (Unix) sürümleri çalıştı
The Red Pea

1
@TheRedPea evet, çünkü Windows dosya sistemi durumu kapatır, yani Templates== templates. Ancak Heroku, Linux'u büyük / küçük harfe duyarlı bir dosya sistemi ile çalıştırır.
Martijn Pieters

13

Sanırım Flask varsayılan olarak dizin şablonlarını kullanıyor. Yani kodunuz, bunun merhaba.py olduğunu varsaymalıdır.

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)

Ve çalışma alanı yapısını şöyle

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

ayrıca home.html ve about.html adlı iki html dosyası oluşturup bu dosyaları şablon klasörüne koyarsınız.


8

(Dosya / proje yapısı için verilen yukarıda kabul edilen Cevabın kesinlikle doğru olduğunu lütfen unutmayın.)

Ayrıca..

Proje dosya yapısını düzgün bir şekilde kurmanın yanı sıra, flask'a dizin hiyerarşisinin uygun seviyesine bakmasını söylemeliyiz.

Örneğin..

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

İle başlamak ../bir dizin geriye doğru gider ve oradan başlar.

İle başlayan ../../(... vb) iki dizinleri geriye hamle ve orada başlar.

Bu yardımcı olur umarım


5

Nedenini bilmiyorum ama bunun yerine aşağıdaki klasör yapısını kullanmak zorunda kaldım. "Şablonları" bir seviye yukarı koydum.

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

Bu muhtemelen başka bir yerde bir yanlış yapılandırma olduğunu gösteriyor, ancak bunun ne olduğunu çözemedim ve bu işe yaradı.


3

Şunu kontrol et:

  1. şablon dosyası doğru ada sahip
  2. şablon dosyası adlı bir alt dizinde templates
  3. ilettiğiniz ad render_template, şablon diziniyle ilişkilidir ( index.htmldoğrudan şablonlar dizininde olur, şablonlar dizinindeki auth/login.htmlauth dizini altında olur.)
  4. uygulamanızla aynı ada sahip bir alt dizininiz yok veya şablonlar dizini bu alt dizinin içindedir.

Bu işe yaramazsa, app.debug = Truesorunun ne olduğunu anlamanıza yardımcı olabilecek hata ayıklamayı ( ) açın.


3

Kodunuzu kurulu bir paketten çalıştırırsanız, dizinde şablon dosyalarının bulunduğundan emin olun <python root>/lib/site-packages/your-package/templates.


Bazı detaylar:

Benim durumumda flask_simple_ui proje örneklerini çalıştırmaya çalışıyordum ve jinjaher zaman

jinja2.exceptions.TemplateNotFound: form.html

İşin püf noktası, örnek programın kurulu paketi içe aktarmasıydı flask_simple_ui. Ve ninjabu paketin içinden kullanılması, benim durumumda ...python/lib/site-packages/flask_simple_ui, os.getcwd() beklendiği gibi değil , paket yolunu aramak için kök dizin olarak kullanılıyor .

Kötü şansıma, setup.pybir bug var ve eksik olanlar dahil hiçbir html dosyasını kopyalamıyor form.html. Düzelttikten sonra TemplateNotFoundsetup.py ile ilgili sorun ortadan kalktı.

Umarım birine yardımcı olur.


2

Aynı hatayı aldım, yanlış yaptığım tek şey 'şablonlar' klasörümü, 's' olmadan 'şablon' olarak adlandırmaktı. Bunu değiştirdikten sonra iyi çalıştı, neden bir şey olduğunu bilmiyorum ama öyle.


2

Render_template () işlevi kullanıldığında, şablonlar adı verilen klasörde şablon aramaya çalışır ve aşağıdaki durumlarda jinja2.exceptions hatası verir.

  1. html dosyası yok veya
  2. şablonlar klasörü olmadığında

Sorunu çözmek :

python dosyasının bulunduğu dizinde ad şablonlarıyla bir klasör oluşturun ve oluşturulan html dosyasını şablonlar klasörüne yerleştirin.


1

Tüm .htmldosyalarınızı python modülünüzün yanındaki şablon klasörüne koymanız gerekir . Ve html dosyalarınızda kullandığınız herhangi bir resim varsa, tüm dosyalarınızı statik adlı klasöre koymanız gerekir.

Aşağıdaki Yapıda

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

1

Diğer bir alternatif, root_pathhem şablonlar hem de statik klasörler için sorunu çözen seçeneği belirlemektir .

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

Şablonları doğrudan aracılığıyla oluşturursanız Jinja2, şunu yazarsınız:

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

0

Benim sorunum, içeriden atıfta bulunduğum dosyanın home.htmla .j2yerine a olması .htmlve onu değiştirdiğimde jinja'nın okuyabilmesiydi.

Aptalca bir hata ama birine yardımcı olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.