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.

- Andrés Cruz

In english
Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz En Udemy

Acepto recibir anuncios de interes sobre este Blog.