Generar el template maestro o base en una app en Django

Generar una vista base para nuestra app en un proceso FUNDAMENTAL para que nuestras aplicaciones sean mantenibles y más fácilmente escalables, ya que supone en nuestro caso que tenemos un par de vistas, la de índice para el listado, y la de detalle de un producto para el show tenemos algo como lo siguiente:

<!DOCTYPE html>
<html lang="es">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>
Listado Productos
   </title>
</head>
<body>
<h1>Hola Mundo</h1>
{% for p in products %}
   <h3>{{ p.title }}</h3>
   <a href="{% url 'gestion:show' p.id %}">Ver</a>
{% endfor %}

<nav>
   {% if products.has_previous  %}
       <a href="?page={{ products.previous_page_number }}">Prev</a>
   {% endif %}
   {% for i in products.paginator.page_range %}
       <a href="?page={{ i }}">{{i }}</a>
   {% endfor %}
       {% if products.has_next  %}
       <a href="?page={{ products.next_page_number }}">Next</a>
   {% endif %}
   
</nav>
   
</body>
</html>

Y la de detalle:

<!DOCTYPE html>
<html lang="es">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>
{{product.title}}
   </title>
</head>
<body>
<h1>{{product.title}}</h1>
   <p>{{product.price}}$</p>
   <p>{{product.category.title}}</p>
   <p>{{product.description}}</p>
</nav>
</body>
</html>

Como puedes ver, el esqueleto del body o HTML se repiten en ambas y lo único que cambia es el contenido que mostramos en el medio.

Entonces, qué pasa si quieres agregar un archivo CSS, JS o cualquier otro elemento HTML que requiera modificar cada una de estas vistas; por ejemplo, un logo; tuvieras que modificar cada uno de estas vistas, en este caso es simple, ya que son solamente 2 templates de nuestra app en Django, pero qué pasa si son 10 paginas la que costa tu aplicación, o 100... ya el problema crece.

O si queremos agregar un menú de navegación, footer o cualquier otro componente.

Generar vista base o maestra en Django

En estos casos la mejor opción es crear una vista base o template para tu aplicación, que puede ser más de una o las que necesites; en este caso, solamente necesitamos uno; creamos una vista:

<!DOCTYPE html>
<html lang="es">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>
   {% block title %}
   
   {% endblock title %}
   </title>
</head>
<body>
   {% block  content %}
   
   {% endblock  %}
</body>
</html>

Como puedes ver, aquí es que tenemos el cuerpo base, la etiqueta HTML, body... y los bloques (block) encierran la parte dinámica, puedes colocar tantos bloques como quieras, en este caso tenemos dos, para el body, en donde colocamos nuestra vista de detalle o el listado... y el título; cada bloque tiene que tener un nombre, que es el ID.

Modificar tus templates de listado, show... y cualquier otro de tu app en Django

Ahora, lo que tenemos que hacer es indicar a nuestros templates que queremos que use el template base anterior, que extienda o herede de esta vista anterior; para eso:

{% extends "base.html" %}

En este template maestro definimos dos bloques, uno llamado content y otro title; con estos podemos colocar cualquier clase de contenido de donde heredamos dicho template; cómo haremos a continuación.

Adaptar el template de listado

{% extends "base.html" %}
{% block title %}
   {{product.title}}
{% endblock title %}
{% block content %}
<h1>{{product.title}}</h1>
   <p>{{product.price}}$</p>
   <p>{{product.category.title}}</p>
   <p>{{product.description}}</p>
   
{% endblock %}

Adaptar el template de listado

{% extends "base.html" %}
{% block title %}
Listado Productos
{% endblock title %}
{% block content %}
<h1>Hola Mundo</h1>
{% for p in products %}
   <h3>{{ p.title }}</h3>
   <a href="{% url 'gestion:show' p.id %}">Ver</a>
{% endfor %}

<nav>
   {% if products.has_previous  %}
       <a href="?page={{ products.previous_page_number }}">Prev</a>
   {% endif %}
   {% for i in products.paginator.page_range %}
       <a href="?page={{ i }}">{{i }}</a>
   {% endfor %}
       {% if products.has_next  %}
       <a href="?page={{ products.next_page_number }}">Next</a>
   {% endif %}
   
</nav>
{% endblock  %}

Conclusiones

Cómo puedes darte cuenta, este es un excelente esquema con el cual puedes reutilizar componentes comunes, en este caso la vista y cuyo término de reutilización es uno de las principales características que tienen este tipo de frameworks.

Acepto recibir anuncios de interes sobre este Blog.

Aprende a crear vistas maestras en Django para reutilizar templates o vistas HTML genéricas.

- Andrés Cruz

In english

) )