Plantilla Jinja2
En este capítulo aprenderás a configurar el motor de plantillas Jinja2 en FastAPI, y a construir páginas HTML completas con archivos estáticos y herencia de plantillas.
Dos modos de renderizado de FastAPI
FastAPI devuelve JSON por defecto (adecuado para API), pero también puede devolver HTML (adecuado para SSR).
Los dos modos pueden coexistir: el mismo proyecto puede ofrecer una API JSON y también renderizar páginas web.
Montar archivos estáticos
Los archivos estáticos (CSS, JS, imágenes)StaticFilesse montan en la ruta especificada.
Ejemplo
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
app = FastAPI()
# Montar el directorio static/ en la ruta /static
# Acceder a /static/css/style.css → en realidad lee static/css/style.css
app.mount("/static", StaticFiles(directory="static"), name="static")
Referenciar archivos estáticos en la plantilla:
Ejemplo
<img src="/static/images/logo.png">
Configurar la plantilla Jinja2
Ejemplo
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
# Especificar el directorio de plantillas
templates = Jinja2Templates(directory="templates")
@app.get("/")
def index(request: Request): # Nota: la ruta de la plantilla debe recibir el parámetro Request
"""Página de inicio del blog"""
return templates.TemplateResponse(
"index.html", # Nombre del archivo de plantilla
{ # Datos de context
"request": request, # request debe pasarse (requisito de Jinja2Templates)
"title": "Blog de EJEMPLO"
}
)
La renderización de plantillas en FastAPI tiene dos diferencias clave con Flask: 1. La función de vista debe recibir
request: Requestel parámetro; 2.requestdebe pasarse a la plantilla como context. Si se omite request, la función url_for de la plantilla dejará de funcionar.
Crear la plantilla padre base.html
Ejemplo
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Blog de EJEMPLO{% endblock %}</title>
<link rel="stylesheet" href="/static/css/style.css">
{% block extra_head %}{% endblock %}
</head>
<body>
<header class="navbar">
<a href="/" class="logo">Blog de EJEMPLO (FastAPI)</a>
<nav>
<a href="/">Inicio</a>
<a href="#">Acerca de</a>
</nav>
</header>
<main class="container">
{% block content %}{% endblock %}
</main>
<footer class="footer">
<p>© 2024 Blog de EJEMPLO. Desarrollado con FastAPI.</p>
</footer>
</body>
</html>
Crear la plantilla hija index.html
Ejemplo
{% extends 'base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h2 class="section-title">Últimos artículos</h2>
<p>La lista de artículos se mostrará en capítulos posteriores.</p>
{% endblock %}
url_for() en plantillas de FastAPI
Al igual que Flask, FastAPI también admiteurl_for(), pero primero es necesario nombrar la ruta.
Ejemplo
def post_detail(request: Request, post_id: int):
return templates.TemplateResponse("post_detail.html",
{"request": request, ...})
Ejemplo
<a href="{{ url_for('post_detail', post_id=3) }}">Artículo 3</a>
Crear estilos CSS básicos
Ejemplo
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f5f5f5;
color: #333;
}
.navbar {
display: flex; justify-content: space-between; align-items: center;
padding: 16px 40px; background: #fff;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.navbar .logo {
font-size: 22px; font-weight: bold;
color: #009688; text-decoration: none;
}
.navbar nav a {
margin-left: 20px; text-decoration: none; color: #333;
}
.container { max-width: 960px; margin: 40px auto; padding: 0 20px; }
.footer { text-align: center; padding: 20px; color: #999; border-top: 1px solid #eee; }
.section-title { font-size: 24px; margin-bottom: 20px; }
Resumen del capítulo
En este capítulo has aprendido la configuración de renderizado frontend en FastAPI: StaticFiles para montar recursos estáticos, Jinja2Templates para configurar el directorio de plantillas, TemplateResponse para devolver HTML, y las diferencias clave con Flask en el renderizado de plantillas (el parámetro Request debe pasarse).
Otras extensiones