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
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter