大丈夫なパターン
htmlファイルのあるフォルダと関数Jinja2Templates
を呼び出すpythonファイルが同一階層の場合は出現しません。
testapp
├ app.py
└ templates
└ index.html
from fastapi import FastAPI
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
from fastapi.requests import Request
app = FastAPI()
templates = Jinja2Templates(directory='templates')
@app.get("/", response_class=HTMLResponse)
def index(request:Request):
return templates.TemplateResponse(
"index.html", {"request": request)
)
エラーが出るパターン
htmlファイルのあるフォルダと関数Jinja2Templates
を呼び出すpythonファイルが同一階層に無い場合にエラーが出現します。
testapp
├ router
│ └ route.py
├ templates
│ └ index.html
└ main.py
from fastapi import FastAPI
from .router import route
app = FastAPI()
app.include_router(route.router)
from fastapi import APIRouter
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
from fastapi.requests import Request
router = APIRouter()
templates = Jinja2Templates(directory='../templates') #ここが問題点!
@router.get("/", response_class=HTMLResponse)
def index(request:Request):
return templates.TemplateResponse(
"index.html",{"request": request}
)
エラーが出ますね
Traceback (most recent call last):
"""
略
"""
jinja2.exceptions.TemplateNotFound: index.html
解決策
rendererファイルにtemplatesファイルを格納し、_init_.pyを追加します。
testapp
├ renderer
│ ├ __init__.py
│ └ templates
│ └ index.html
├ router
│ └ route.py
└ main.py
main.py
は変わりません。
router/route.py
ではテンプレートエンジンを作成せず、新しく作ったディレクトリrenderer
よりエンジンをインポートします。
from fastapi import APIRouter
from fastapi.responses import HTMLResponse
from fastapi.requests import Request
from renderer import loader #rendererからテンプレートエンジンを読み込む
router = APIRouter()
@router.get("/", response_class=HTMLResponse)
def index(request:Request):
template = loader.get_template('index.html')
return template.render(request=request)
renderer/__init__.py
ではテンプレートフォルダを指定しエンジンを作成します。
from jinja2 import Environment, PackageLoader, select_autoescape
loader = Environment(
loader=PackageLoader('renderer', 'templates'),
autoescape=select_autoescape(['html', 'xml'])
)
これで実行できます。
テンプレートに変数を埋め込むときは関数template.render()
に引数を追加します。例えばindex.htmlに{{name}}
と書き込み、変数name
を埋め込む場合はtemplate.render(name="hogehoge")
と書き込めます。