Flask ทำให้เกิดข้อผิดพลาด TemplateNotFound แม้ว่าจะมีไฟล์เทมเพลตอยู่ก็ตาม


118

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

คำตอบ:


239

คุณต้องสร้างไฟล์เทมเพลตของคุณในตำแหน่งที่ถูกต้อง ในtemplatesไดเร็กทอรีย่อยถัดจากโมดูล python ของคุณ

ข้อผิดพลาดระบุว่าไม่มีhome.htmlไฟล์ในtemplates/ไดเร็กทอรี ตรวจสอบให้แน่ใจว่าคุณได้สร้างไดเร็กทอรีนั้นในไดเร็กทอรีเดียวกับโมดูล python ของคุณและคุณได้ใส่home.htmlไฟล์ในไดเร็กทอรีย่อยนั้น หากแอปของคุณเป็นแพ็กเกจควรสร้างโฟลเดอร์เทมเพลตภายในแพ็กเกจ

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

หรือหากคุณตั้งชื่อโฟลเดอร์เทมเพลตเป็นอย่างอื่นtemplatesและไม่ต้องการเปลี่ยนชื่อเป็นค่าเริ่มต้นคุณสามารถบอกให้ Flask ใช้ไดเร็กทอรีอื่นนั้นได้

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

คุณสามารถขอขวดที่จะอธิบายถึงวิธีการที่จะพยายามที่จะหาแม่แบบที่กำหนดโดยการตั้งค่าEXPLAIN_TEMPLATE_LOADINGตัวเลือกTrueที่จะ ทุกเทมเพลตโหลดคุณจะได้รับรายงานที่บันทึกลงในขวดapp.loggerINFOที่ระดับ

นี่คือสิ่งที่ดูเหมือนว่าเมื่อการค้นหาประสบความสำเร็จ ในตัวอย่างนี้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 จะถูกค้นหาก่อนเสมอแม้ว่าจะใช้เส้นทางเพิ่มเติมต่อพิมพ์เขียวก็ตาม


2
ดูเหมือนว่ากระติกน้ำในเครื่องของฉัน (บน Windows) สามารถค้นหาเทมเพลตภายใน./Templates/index.htmlได้ แต่เมื่อฉันปรับใช้กับ heroku (คิดว่ามันเป็น Python เดียวกันเวอร์ชันไลบรารีเดียวกันรวมถึงรุ่น Flask เดียวกัน แต่ heroku เป็น Unix); และโยนTemplateNotFoundข้อผิดพลาด หลังจากที่ฉันเปลี่ยนชื่อโฟลเดอร์git mv Templates/index.html templates/index.htmlทั้งเวอร์ชันในเครื่อง (Windows) และเวอร์ชัน heroku (Unix) ใช้งานได้
The Red Pea

1
@TheRedPea ใช่เพราะระบบแฟ้มของ Windows พับกรณีเพื่อให้==Templates templatesแต่ Heroku ใช้งาน Linux ด้วยระบบไฟล์ที่คำนึงถึงตัวพิมพ์เล็กและใหญ่
Martijn Pieters

14

ฉันคิดว่า Flask ใช้เทมเพลตไดเร็กทอรีโดยค่าเริ่มต้น ดังนั้นโค้ดของคุณควรสมมติว่านี่คือ 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 และวางไฟล์เหล่านั้นไว้ในโฟลเดอร์เทมเพลต


8

(โปรดทราบว่าคำตอบที่ยอมรับข้างต้นที่ให้ไว้สำหรับโครงสร้างไฟล์ / โครงการนั้นถูกต้องอย่างแน่นอน)

นอกจากนี้ ..

นอกเหนือจากการตั้งค่าโครงสร้างไฟล์โปรเจ็กต์อย่างถูกต้องแล้วเรายังต้องบอกให้ flask ดูในระดับที่เหมาะสมของลำดับชั้นของไดเร็กทอรี

ตัวอย่างเช่น..

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

เริ่มต้นด้วยการ../ย้ายหนึ่งไดเรกทอรีไปข้างหลังและเริ่มต้นที่นั่น

เริ่มต้นด้วยการ../../ย้ายสองไดเรกทอรีไปข้างหลังและเริ่มต้นที่นั่น (และอื่น ๆ ... )

หวังว่านี่จะช่วยได้


5

ฉันไม่รู้ว่าทำไม แต่ฉันต้องใช้โครงสร้างโฟลเดอร์ต่อไปนี้แทน ฉันใส่ "เทมเพลต" ขึ้นหนึ่งระดับ

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

สิ่งนี้อาจบ่งบอกถึงการกำหนดค่าที่ผิดพลาดที่อื่น แต่ฉันคิดไม่ออกว่ามันคืออะไรและได้ผล


คุณแน่ใจว่าคุณมีapp = Flask(__name__)?
Nikhil CSB

3

ตรวจสอบว่า:

  1. ไฟล์เทมเพลตมีชื่อที่ถูกต้อง
  2. ไฟล์เทมเพลตอยู่ในไดเร็กทอรีย่อยที่เรียกว่า templates
  3. ชื่อที่คุณส่งผ่านrender_templateสัมพันธ์กับไดเร็กทอรี template ( index.htmlจะอยู่ในไดเร็กทอรี template โดยตรงauth/login.htmlจะอยู่ภายใต้ไดเร็กทอรี auth ในไดเร็กทอรี template)
  4. คุณไม่มีไดเร็กทอรีย่อยที่มีชื่อเดียวกับแอปของคุณหรือไดเร็กทอรีเทมเพลตอยู่ภายในไดเร็กทอรีย่อยนั้น

หากไม่ได้ผลให้เปิดการดีบัก ( app.debug = True) ซึ่งอาจช่วยให้ทราบว่ามีอะไรผิดปกติ


3

<python root>/lib/site-packages/your-package/templatesถ้าคุณเรียกใช้รหัสของคุณจากแพคเกจติดตั้งให้แน่ใจว่าแฟ้มแม่แบบที่มีอยู่ในไดเรกทอรี


รายละเอียดบางส่วน:

ในกรณีของฉันฉันพยายามเรียกใช้ตัวอย่างของโครงการflask_simple_uiและjinjaมักจะพูดเสมอ

jinja2.exceptions.TemplateNotFound: form.html

flask_simple_uiเคล็ดลับก็คือว่าโปรแกรมตัวอย่างจะนำเข้าแพคเกจติดตั้ง และninjaการใช้งานจากภายในแพ็กเกจนั้นใช้เป็นไดเร็กทอรีรูทเพื่อค้นหาพา ธ แพ็กเกจในกรณีของฉัน...python/lib/site-packages/flask_simple_uiแทนที่จะos.getcwd() เป็นอย่างที่คาดหวัง

สำหรับความโชคร้ายของฉันsetup.pyมีข้อผิดพลาดและไม่ได้คัดลอกไฟล์ html ใด ๆ รวมถึงไฟล์form.html. เมื่อฉันแก้ไขsetup.pyปัญหาเกี่ยวกับTemplateNotFoundก็หายไป

ฉันหวังว่ามันจะช่วยใครสักคน


2

ฉันมีข้อผิดพลาดเดียวกันปรากฎว่าสิ่งเดียวที่ฉันทำผิดคือตั้งชื่อโฟลเดอร์ 'แม่แบบ' ของฉันว่า 'แม่แบบ' โดยไม่มี 's' หลังจากเปลี่ยนแล้วมันใช้งานได้ดีไม่รู้ว่าทำไมมันถึงเป็นเช่นนั้น


2

เมื่อใช้ฟังก์ชัน render_template () จะพยายามค้นหาเทมเพลตในโฟลเดอร์ที่เรียกว่า template และแสดงข้อผิดพลาด jinja2.exceptions.TemplateNotFound เมื่อ:

  1. ไม่มีไฟล์ html หรือ
  2. เมื่อไม่มีโฟลเดอร์เทมเพลต

วิธีแก้ปัญหา:

สร้างโฟลเดอร์ที่มีเทมเพลตชื่อในไดเร็กทอรีเดียวกับที่มีไฟล์ python และวางไฟล์ html ที่สร้างในโฟลเดอร์ template


1

คุณต้องใส่.htmlไฟล์ทั้งหมดของคุณในโฟลเดอร์เทมเพลตถัดจากโมดูล python ของคุณ และหากมีภาพใด ๆ ที่คุณใช้ในไฟล์ html ของคุณคุณต้องใส่ไฟล์ทั้งหมดของคุณในโฟลเดอร์ที่ชื่อstatic

ในโครงสร้างต่อไปนี้

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

1

อีกทางเลือกหนึ่งคือการตั้งค่า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)

0

ปัญหาของฉันคือไฟล์ที่ฉันอ้างถึงจากภายในของฉันhome.htmlเป็น a .j2แทนที่จะเป็น a .htmlและเมื่อฉันเปลี่ยนกลับ jinja ก็สามารถอ่านได้

ข้อผิดพลาดโง่ ๆ แต่อาจช่วยใครบางคนได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.