🌐 Перевод выполнен с помощью ИИ и людей
Этот перевод был сделан ИИ под руководством людей. 🤝
В нем могут быть ошибки из-за неправильного понимания оригинального смысла или неестественности и т. д. 🤖
Вы можете улучшить этот перевод, помогая нам лучше направлять ИИ LLM.
Шаблоны¶
Вы можете использовать любой шаблонизатор вместе с FastAPI.
Часто выбирают Jinja2 — тот же, что используется во Flask и других инструментах.
Есть утилиты для простой настройки, которые вы можете использовать прямо в своем приложении FastAPI (предоставляются Starlette).
Установка зависимостей¶
Добавьте jinja2 в ваш проект:
$ uv add jinja2
---> 100%
Использование Jinja2Templates¶
- Импортируйте
Jinja2Templates. - Создайте объект
templates, который сможете переиспользовать позже. - Объявите параметр
Requestв операции пути, которая будет возвращать шаблон. - Используйте созданный
templates, чтобы отрендерить и вернутьTemplateResponse; передайте имя шаблона, объект HTTP-запроса и словарь «context» с парами ключ-значение для использования внутри шаблона Jinja2.
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/items/{id}", response_class=HTMLResponse)
async def read_item(request: Request, id: str):
return templates.TemplateResponse(
request=request, name="item.html", context={"id": id}
)
Примечание
До FastAPI 0.108.0, Starlette 0.29.0, name был первым параметром.
Также раньше, в предыдущих версиях, объект request передавался как часть пар ключ-значение в контексте для Jinja2.
Совет
Если указать response_class=HTMLResponse, интерфейс документации сможет определить, что HTTP-ответ будет в формате HTML.
Технические детали
Можно также использовать from starlette.templating import Jinja2Templates.
FastAPI предоставляет тот же starlette.templating как fastapi.templating просто для удобства разработчика. Но большинство доступных HTTP-ответов приходят напрямую из Starlette. Так же и с Request и StaticFiles.
Написание шаблонов¶
Затем вы можете создать шаблон в templates/item.html, например:
<html>
<head>
<title>Item Details</title>
<link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
</head>
<body>
<h1><a href="{{ url_for('read_item', id=id) }}">Item ID: {{ id }}</a></h1>
</body>
</html>
Значения контекста шаблона¶
В HTML, который содержит:
Item ID: {{ id }}
...будет отображён id, взятый из переданного вами «context» dict:
{"id": id}
Например, для ID 42 это отрендерится как:
Item ID: 42
Аргументы url_for в шаблоне¶
Вы также можете использовать url_for() внутри шаблона — он принимает те же аргументы, что использовались бы вашей функцией-обработчиком пути.
Таким образом, фрагмент:
<a href="{{ url_for('read_item', id=id) }}">
...сгенерирует ссылку на тот же URL, который обрабатывается функцией-обработчиком пути read_item(id=id).
url_for() возвращает абсолютный URL, включая схему и хост, на основе текущего HTTP-запроса.
Например, если ваше приложение доступно по адресу https://example.com, для ID 42 это отрендерится как:
<a href="https://example.com/items/42">
Пути URL в шаблонах¶
Для ссылок на тот же сайт можно использовать атрибут .path, чтобы получить только путь URL, например, в templates/item_path.html:
<html>
<head>
<title>Item Details</title>
<link href="{{ url_for('static', path='/styles.css').path }}" rel="stylesheet">
</head>
<body>
<h1><a href="{{ url_for('read_item', id=id).path }}">Item ID: {{ id }}</a></h1>
</body>
</html>
Передайте имя шаблона в TemplateResponse:
# Code above omitted 👆
@app.get("/items/{id}", response_class=HTMLResponse)
async def read_item(request: Request, id: str):
return templates.TemplateResponse(
request=request, name="item_path.html", context={"id": id}
)
👀 Full file preview
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/items/{id}", response_class=HTMLResponse)
async def read_item(request: Request, id: str):
return templates.TemplateResponse(
request=request, name="item_path.html", context={"id": id}
)
В том же примере ссылка на элемент отрендерится как:
<a href="/items/42">
Начальный / делает этот путь относительным к корню текущего сайта.
Атрибут .path не включает схему, хост, параметры запроса и фрагмент. Для ссылок на другой хост используйте полный URL.
Совет
Если ваше приложение находится за прокси-сервером, настройте HTTP-заголовки переадресации и root_path, как описано в разделе За прокси-сервером.
Шаблоны и статические файлы¶
Вы также можете использовать url_for() внутри шаблона, например, с StaticFiles, которые вы монтировали с name="static".
<html>
<head>
<title>Item Details</title>
<link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
</head>
<body>
<h1><a href="{{ url_for('read_item', id=id) }}">Item ID: {{ id }}</a></h1>
</body>
</html>
В этом примере будет создана ссылка на CSS-файл static/styles.css с помощью:
h1 {
color: green;
}
И, так как вы используете StaticFiles, этот CSS-файл будет автоматически «отдаваться» вашим приложением FastAPI по URL /static/styles.css.
Подробнее¶
Больше подробностей, включая то, как тестировать шаблоны, смотрите в документации Starlette по шаблонам.