La plantilla base
La herencia de plantillas es una de las características más potentes del sistema de plantillas de Django. Permite definir una estructura HTML común (base.html) que todas las páginas del sitio extienden, sobreescribiendo solo las secciones específicas de cada página.
Crea la plantilla base en templates/base.html:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block titulo %}Mi Sitio Web{% endblock %}</title>
{% block estilos_extra %}{% endblock %}
<link rel="stylesheet" href="{% static 'css/estilos.css' %}">
</head>
<body>
<header>
<nav>
<a href="{% url 'inicio' %}">Inicio</a>
<a href="{% url 'catalogo:producto-list' %}">Productos</a>
{% if user.is_authenticated %}
<a href="{% url 'logout' %}">Salir ({{ user.username }})</a>
{% else %}
<a href="{% url 'login' %}">Iniciar sesión</a>
{% endif %}
</nav>
</header>
<main class="contenido-principal">
{% block mensajes %}
{% for mensaje in messages %}
<div class="alerta alerta-{{ mensaje.tags }}">{{ mensaje }}</div>
{% endfor %}
{% endblock %}
{% block contenido %}
<!-- Las páginas hijas insertan su contenido aquí -->
{% endblock %}
</main>
<footer>
<p>© 2026 Mi Sitio Web</p>
</footer>
{% block scripts_extra %}{% endblock %}
</body>
</html>

Extender la plantilla base
Las plantillas hijas usan {% extends %} como primera línea y sobreescriben los bloques necesarios:
<!-- catalogo/templates/catalogo/producto_list.html -->
{% extends "base.html" %}
{% block titulo %}Catálogo de productos{% endblock %}
{% block contenido %}
<section class="catalogo">
<h1>Catálogo de productos</h1>
<div class="productos-grid">
{% for producto in productos %}
<article class="producto-card">
<h2>{{ producto.nombre }}</h2>
<p class="precio">{{ producto.precio }} €</p>
<a href="{{ producto.get_absolute_url }}">Ver detalle</a>
</article>
{% empty %}
<p>No hay productos disponibles.</p>
{% endfor %}
</div>
</section>
{% endblock %}
La etiqueta include
{% include %} inserta una sub-plantilla en el punto donde se llama, pasando el contexto actual automáticamente:
<!-- templates/componentes/tarjeta_producto.html -->
<div class="producto-card">
<h3>{{ producto.nombre }}</h3>
<p>{{ producto.precio }} €</p>
{% if producto.en_oferta %}
<span class="badge-oferta">Oferta</span>
{% endif %}
</div>
<!-- En otra plantilla -->
{% for producto in productos %}
{% include "componentes/tarjeta_producto.html" %}
{% endfor %}
<!-- Pasando variables adicionales (solo disponibles en la sub-plantilla) -->
{% include "componentes/tarjeta_producto.html" with mostrar_precio=True solo_nombre=True %}
<!-- Solo con las variables indicadas (sin el contexto padre) -->
{% include "componentes/tarjeta_producto.html" with producto=producto_destacado only %}
Múltiples niveles de herencia
Es posible crear jerarquías de plantillas con más de dos niveles:
<!-- templates/base.html: layout principal -->
<!-- templates/layouts/con_sidebar.html: extiende base, añade sidebar -->
<!-- templates/catalogo/producto_list.html: extiende con_sidebar -->
<!-- templates/layouts/con_sidebar.html -->
{% extends "base.html" %}
{% block contenido %}
<div class="layout-dos-columnas">
<aside class="sidebar">
{% block sidebar %}{% endblock %}
</aside>
<main>
{% block contenido_principal %}{% endblock %}
</main>
</div>
{% endblock %}
<!-- catalogo/producto_list.html -->
{% extends "layouts/con_sidebar.html" %}
{% block titulo %}Catálogo{% endblock %}
{% block sidebar %}
<h3>Filtrar por categoría</h3>
{% for cat in categorias %}
<a href="?categoria={{ cat.slug }}">{{ cat.nombre }}</a>
{% endfor %}
{% endblock %}
{% block contenido_principal %}
<!-- Lista de productos -->
{% endblock %}
super() en bloques
Para añadir contenido al bloque padre sin sustituirlo completamente, usa {{ block.super }}:
<!-- En una plantilla hija que quiere añadir un CSS extra al del padre -->
{% block estilos_extra %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'css/catalogo.css' %}">
{% endblock %}
Configuración del directorio de plantillas
Django busca plantillas según la configuración de TEMPLATES en settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # Plantillas globales del proyecto
'APP_DIRS': True, # Busca en app/templates/ de cada app registrada
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Con APP_DIRS: True, Django busca automáticamente plantillas en <nombre_app>/templates/ dentro de cada aplicación registrada en INSTALLED_APPS.
La herencia de plantillas es fundamental para mantener la coherencia visual del sitio y reducir la duplicación de HTML, permitiendo cambiar el layout global desde un único archivo.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Django es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Django
Explora más contenido relacionado con Django y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Crear una plantilla base con bloques que las páginas hijas pueden sobreescribir. Usar la etiqueta extends para heredar de una plantilla padre. Definir y sobreescribir bloques con block y endblock. Incluir fragmentos de plantilla reutilizables con include. Estructurar un proyecto con múltiples niveles de herencia para layouts complejos.