Cómo crear páginas web dinámicas con plantillas Jinja en FastAPI
Las plantillas de Jinja ofrecen un lenguaje potente que puedes utilizar para crear páginas web dinámicas con facilidad.
La integración de Jinja con FastAPI le permite crear páginas web dinámicas que combinan perfectamente el código Python con HTML, lo que le permite separar la capa de presentación de su aplicación de la capa lógica. Con páginas web dinámicas, puede generar contenido personalizado y basado en datos, mejorando la experiencia del usuario.
¿Qué es Jinja?
Jinja es un motor de plantillas robusto y rico en funciones para Python que genera páginas web dinámicas. Jinja Templating admite herencia, declaraciones condicionales, bucles y varias funciones que simplifican la creación de páginas web dinámicas.
Puede combinar FastAPI y Jinja para crear páginas web con un diseño consistente que pueda mostrar datos en tiempo real y manejar la entrada del usuario. También puede lograr la separación de preocupaciones, haciendo que su código sea más fácil de mantener y de entender.
Configurar un proyecto FastAPI
Para comenzar, deberá configurar un proyecto FastAPI.
-
Cree y active un entorno virtual utilizando estos comandos de terminal:
python -m venv env # On Unix/MacOS: source venv/bin/activate # On Windows: .\venv\Scripts\activate
Instale FastAPI y las dependencias necesarias.
pip install "fastapi[all]"
- Cree un directorio de proyecto my_blog.
- Cree un archivo Python main.py en el directorio de su proyecto.
Agregue el siguiente código al archivo main.py:
from fastapi import FastAPI fake_posts_db = [{ 'title': 'First Blog Post', 'content': 'Content of the first blog post.', 'author': 'John Doe', 'publication_date': '2023-06-20', 'comments': [ {'author': 'Alice', 'content': 'Great post!'}, {'author': 'Bob', 'content': 'Intresting read.'} ], 'status': 'published' },{ 'title': 'Second Blog Post', 'content': 'Content of the second blog post.', 'author': 'Jane Smith', 'publication_date': None, 'comments': [], 'status': 'draft' }] app = FastAPI() @app.get("/about") def about(): return "All you need to know about Simple Blog"
Ejecute el servidor.
uvicorn main:app --reload
Visite http://localhost:8000/about en su navegador para ver la respuesta del servidor.
Integración de plantillas Jinja
Después de haber configurado correctamente su proyecto, ahora puede agregarle plantillas de Jinja.
En el archivo main.py, importe los siguientes módulos:
from fastapi.templating import Jinja2Templates from fastapi.staticfiles import StaticFiles
Debajo de la variable app, cree una instancia de la clase Jinja2Templates y pase el directorio que contendrá sus plantillas.
templates = Jinja2Templates(directory="templates")
Después de la variable templates, agregue la siguiente línea de código:
app.mount("/static", StaticFiles(directory="static"), name="static")
En el directorio my_blog cree dos directorios, templates para contener archivos HTML y static que contendrá todos los archivos estáticos.
Una vez completados estos pasos, habrá integrado exitosamente Jinja Templating con su proyecto.
Creando una página web dinámica con Jinja
Jinja proporciona un amplio conjunto de sintaxis y funciones para crear plantillas dinámicas.
En esta sección, verá cómo utilizar la sintaxis de plantillas de Jinja para crear páginas web dinámicas.
Etiquetas de plantilla
Adjunte las etiquetas de plantilla con una llave y un símbolo de porcentaje en ambos lados. Puede utilizar dichas etiquetas para realizar operaciones lógicas y de flujo de control en la plantilla. Algunas etiquetas de plantilla comúnmente utilizadas incluyen:
Condición: ejecuta el bloque de código si la condición es verdadera.
{% if condition %}...{% endif %}
Bucle: itera sobre un iterable y ejecuta el bloque de código para cada elemento.
{% for item in iterable %}...{% endfor %}
Incluir: incluye otra plantilla dentro de la plantilla actual.
{% include 'template_name.html' %}
Bloque: define un bloque que las plantillas secundarias pueden anular mediante herencia.
{% block block_name %}...{% endblock %}
Extender: permite que la plantilla secundaria herede y extienda la plantilla principal.
{% extend parent_temp.html %}
Estas etiquetas proporcionan una forma flexible y expresiva de generar contenido HTML basado en datos dinámicos y controlar la lógica de su aplicación.
Herencia de plantilla
Jinja Templating admite la herencia de plantillas. Esto le permite definir una plantilla base (principal) con un diseño común y secciones que una plantilla secundaria puede ampliar o anular. Una plantilla secundaria puede utilizar la etiqueta Extend para heredar y ampliar la plantilla principal.
Cree un archivo base.html en el directorio templates con el siguiente código.
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Simple Blog{% endblock %}</title>
</head>
<body>
<h1>{% block heading %}Simple Blog{% endblock %}</h1>
{% block content %}
{% endblock %}
{% include "footer.html" %}
</body>
</html>
De esta manera, tendrá una plantilla principal que contiene el código común para todas sus plantillas, lo que permitirá que la plantilla secundaria lo herede y lo extienda según sea necesario.
En el directorio templates cree un archivo footer.html con el siguiente código.
<footer>
<p>© 2023 Simple Blog. All rights reserved.</p>
<a href="{{ url_for('about') }}">About</a>
</footer>
footer.html es una plantilla incluida que contiene el código HTML para la sección de pie de página. Puede reutilizarlo en varias páginas incluyéndolo en la plantilla base usando la etiqueta Incluir.
En el directorio templates cree un archivo blog.html con el siguiente código.
{% extends "base.html" %}
{% block title %}Simple Blog - Blog Page{% endblock %}
{% block heading %}Simple Blog - Blog Page{% endblock %}
{% block content %}
<h2>Total Number of Posts: {{ posts|length }}</h2>
{% for post in posts %}
<div class="post">
{% if post.status == 'published' %}
<h3>{{ post.title }}</h3>
<p>{{ post.content|truncate }}</p>
<p>Published on: {{ post.publication_date }}</p>
<h4>Comments:</h4>
<ul>
{% for comment in post.comments %}
<li class="comment">{{ comment.author }}-: {{ comment.content }}</li>
{% endfor %}
</ul>
{% else %}
<p>This post is still in draft mode.</p>
{% endif %}
</div>
<hr>
{% endfor %}
{% endblock %}
Esta plantilla secundaria hereda de base.html mediante la etiqueta Extend. Anula bloques específicos definidos en la plantilla base para proporcionar contenido personalizado para la página del blog. También incluye la lógica y la iteración necesarias para mostrar una publicación y los comentarios asociados.
Expresiones
Jinja admite una amplia gama de expresiones, incluidas operaciones aritméticas, comparaciones y operaciones lógicas. Por ejemplo:
{{2 + 2}} // output: 4
Sustitución de variables
Para generar variables en la plantilla, enciérrelas entre llaves dobles. Por ejemplo:
{{post.title}} // output: 'First Blog Post'
Filtros
Los filtros modifican la salida de una variable. Puede agregar uno después de una variable usando el símbolo de barra vertical (|). Por ejemplo:
{{post|length}} // output: 2
Comentarios
Puede agregar comentarios en línea y comentarios multilínea en sus plantillas. Jinja ignorará estos comentarios durante la representación de la plantilla, por lo que son útiles para agregar explicaciones dentro de una plantilla.
{# #} // inline
{% comment %} ... {% end comment %} // multiline
URL
Para permitirle generar hipervínculos correctos a otras páginas dentro de la aplicación, el contexto de la plantilla Jinja incluye una función url_for. Por ejemplo:
<a href="{{ url_for('about') }}">About</a>
El código anterior se convierte en http://localhost:8000/about. También verás cómo utilizar la función url_for para obtener rutas de archivos estáticas más adelante.
Estos son sólo algunos de los aspectos fundamentales de la sintaxis de Jinja Templating. Jinja Templating proporciona muchas más características y funcionalidades, como macros, contexto de plantilla y más, para que la creación y personalización de plantillas sea eficiente y flexible.
Pasar datos a plantillas
Ahora que tiene sus plantillas listas, debe pasar datos desde sus puntos finales FastAPI a las plantillas para su procesamiento.
Agregue el siguiente código al archivo main.py:
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
@app.get("/", response_class=HTMLResponse)
async def read_posts(request: Request):
return templates.TemplateResponse("blog.html", {"request": request,
"posts": fake_posts_db})
El código define un punto final FastAPI que maneja una solicitud GET a la URL raíz ("/") y devuelve una HTMLResponse generada a partir de la plantilla blog.html. Pasa un diccionario de contexto, que contiene el objeto de solicitud actual y fake_posts_db, a la plantilla. De esta manera, Jinja puede generar datos precisos y dinámicos.
Visita http://localhost:8000/ en tu navegador y deberías ver algo como esto:
Ha pasado datos exitosamente a las plantillas para su procesamiento.
Sirviendo archivos estáticos
Además de representar plantillas dinámicas, FastAPI también proporciona funcionalidad para entregar archivos estáticos como archivos CSS, archivos JavaScript e imágenes.
Utilizará CSS para mejorar la apariencia de la página.
En el directorio static, cree un archivo styles.css con el siguiente código.
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
h1, h2, h3, h4 {
color: #333;
}
.post {
background-color: #fff;
padding: 20px;
margin-bottom: 20px;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.post h3 {
margin-top: 0;
}
.post p {
margin-bottom: 10px;
}
.post ul {
list-style-type: none;
padding-left: 0;
}
.comment {
margin-bottom: 10px;
padding: 10px;
background-color: #f9f9f9;
border-radius: 5px;
}
footer {
background-color: #f2f2f2;
padding: 10px;
text-align: center;
}
Modifique el elemento head de la plantilla base.html de la siguiente manera:
<head>
<title>{% block title %}Simple Blog{% endblock %}</title>
<link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
</head>
La función url_for() genera una URL (ruta) para el archivo styles.css (/static/styles.css) en el directorio static que luego FastAPI proporciona automáticamente .
Visite http://localhost:8000/ en su navegador.
Los mismos procedimientos se aplican al servicio de archivos de imágenes y JavaScript.
Recuerde seguir las mejores prácticas
Cuando se trabaja con Jinja Templating en FastAPI, es importante seguir ciertas mejores prácticas para garantizar una base de código eficiente y bien organizada.
- Organice las plantillas en un directorio dedicado y considere usar subdirectorios para plantillas relacionadas.
- Utilice la herencia de plantillas para crear plantillas base reutilizables y ampliarlas para contenido específico.
- Seleccione cuidadosamente los datos para pasar a las plantillas, mantenga la carga útil liviana y use procesadores de contexto o middleware para los datos de uso común.
- Utilice las funciones de Jinja Templating, como macros, filtros y estructuras de control, para mejorar la reutilización y legibilidad del código.
- Optimice el rendimiento implementando estrategias de almacenamiento en caché para plantillas estáticas, utilizando encabezados de almacenamiento en caché HTTP y creando perfiles para cuellos de botella en el rendimiento.
Si sigue estas mejores prácticas, puede mantener un proyecto estructurado, optimizar el rendimiento de renderizado y aprovechar de manera eficiente las funciones de Jinja Templating en sus aplicaciones FastAPI.
Uso de FastAPI para crear RestAPI
Además de crear aplicaciones que requieren plantillas de renderizado. FastAPI se destaca en la creación de RestAPI debido a su alto rendimiento, sintaxis fácil de usar, generación automática de documentación y escalabilidad. Estas características hacen que FastAPI sea ideal para el desarrollo eficiente de API web sólidas.