Plantillas¶
AI coding agents
Use the official FastAPI skill for your installed version. Install it from your project directory:
uvx library-skills
See Develop with AI.
🌐 Traducción por IA y humanos
Esta traducción fue hecha por IA guiada por humanos. 🤝
Podría tener errores al interpretar el significado original, o sonar poco natural, etc. 🤖
Puedes mejorar esta traducción ayudándonos a guiar mejor al LLM de IA.
Puedes usar cualquier motor de plantillas que desees con FastAPI.
Una elección común es Jinja2, el mismo que usa Flask y otras herramientas.
Hay utilidades para configurarlo fácilmente que puedes usar directamente en tu aplicación de FastAPI (proporcionadas por Starlette).
Instala dependencias¶
Añade jinja2 a tu proyecto:
$ uv add jinja2
---> 100%
Usando Jinja2Templates¶
- Importa
Jinja2Templates. - Crea un objeto
templatesque puedas reutilizar más tarde. - Declara un parámetro
Requesten la path operation que devolverá una plantilla. - Usa los
templatesque creaste para renderizar y devolver unTemplateResponse, pasa el nombre de la plantilla, el objeto de request, y un diccionario "context" con pares clave-valor que se usarán dentro de la plantilla 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}
)
Nota
Antes de FastAPI 0.108.0, Starlette 0.29.0, el name era el primer parámetro.
Además, antes de eso, en versiones anteriores, el objeto request se pasaba como parte de los pares clave-valor en el contexto para Jinja2.
Consejo
Al declarar response_class=HTMLResponse, la interfaz de usuario de la documentación podrá saber que el response será HTML.
Detalles técnicos
También podrías usar from starlette.templating import Jinja2Templates.
FastAPI proporciona el mismo starlette.templating como fastapi.templating, solo como una conveniencia para ti, el desarrollador. Pero la mayoría de los responses disponibles vienen directamente de Starlette. Lo mismo con Request y StaticFiles.
Escribiendo plantillas¶
Luego puedes escribir una plantilla en templates/item.html con, por ejemplo:
<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>
Valores de Contexto de la Plantilla¶
En el HTML que contiene:
Item ID: {{ id }}
...mostrará el id tomado del dict de "contexto" que pasaste:
{"id": id}
Por ejemplo, con un ID de 42, esto se renderizaría como:
Item ID: 42
Argumentos de la Plantilla url_for¶
También puedes usar url_for() dentro de la plantilla, toma como argumentos los mismos que usaría tu path operation function.
Entonces, la sección con:
<a href="{{ url_for('read_item', id=id) }}">
...generará un enlace hacia la misma URL que manejaría la path operation function read_item(id=id).
url_for() devuelve una URL absoluta, incluidos el esquema y el host, basada en el request actual.
Por ejemplo, si tu aplicación se sirve en https://example.com, con un ID de 42, esto se renderizaría como:
<a href="https://example.com/items/42">
Paths de URL en plantillas¶
Para enlaces al mismo sitio, puedes usar el atributo .path para obtener solo el path de la URL, por ejemplo, en 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>
Pasa el nombre de la plantilla a 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}
)
Con el mismo ejemplo, el enlace al ítem se renderizaría como:
<a href="/items/42">
La / inicial hace que este path sea relativo a la raíz del sitio actual.
El atributo .path excluye el esquema, el host, los parámetros de query y el fragmento. Usa la URL completa para enlaces a otro host.
Consejo
Si tu aplicación está detrás de un proxy, configura los headers reenviados y root_path como se describe en Detrás de un proxy.
Plantillas y archivos estáticos¶
También puedes usar url_for() dentro de la plantilla, y usarlo, por ejemplo, con los StaticFiles que montaste con el 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>
En este ejemplo, enlazaría a un archivo CSS en static/styles.css con:
h1 {
color: green;
}
Y porque estás usando StaticFiles, ese archivo CSS sería servido automáticamente por tu aplicación de FastAPI en la URL /static/styles.css.
Más detalles¶
Para más detalles, incluyendo cómo escribir pruebas para plantillas, revisa la documentación de Starlette sobre plantillas.