📝 Html Css

Django: Template Inheritance

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
2 min
👁️
Views
75
🌿
Level
Medium

Without inheritance, every HTML template would contain duplicated code: navigation, CSS/JS links, footer. Inheritance lets you write a page skeleton once and extend it in child templates.

How It Works

  1. base.html — a skeleton with placeholder blocks ({% block %})
  2. A child template declares {% extends 'base.html' %} and fills in the blocks

When rendering, Django takes the child template, finds the parent, and inserts the block contents.

base.html for DevBlog

{# templates/base.html #}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>{% block title %}DevBlog{% endblock %}</title>

  {% load static %}
  <link rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
  <link rel="stylesheet" href="{% static 'css/main.css' %}">

  {% block extra_css %}{% endblock %}
</head>
<body>

  <!-- Navigation -->
  <nav class="navbar navbar-expand-lg bg-dark navbar-dark">
    <div class="container">
      <a class="navbar-brand" href="{% url 'post-list' %}">DevBlog</a>
      <button class="navbar-toggler" type="button"
              data-bs-toggle="collapse" data-bs-target="#navMenu">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navMenu">
        <ul class="navbar-nav ms-auto">
          <li class="nav-item">
            <a class="nav-link" href="{% url 'post-list' %}">Articles</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="{% url 'about' %}">About</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>

  <!-- Django flash messages -->
  {% if messages %}
    <div class="container mt-3">
      {% for message in messages %}
        <div class="alert alert-{{ message.tags }} alert-dismissible fade show">
          {{ message }}
          <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
        </div>
      {% endfor %}
    </div>
  {% endif %}

  <!-- Main content -->
  <main class="container py-4">
    {% block content %}{% endblock %}
  </main>

  <!-- Footer -->
  <footer class="bg-dark text-light py-4 mt-5">
    <div class="container text-center">
      <p class="mb-0">© {{ now.year }} DevBlog. Built with Django.</p>
    </div>
  </footer>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
  {% block extra_js %}{% endblock %}

</body>
</html>

Blocks in base.html:

Block Purpose
{% block title %} Browser tab title
{% block extra_css %} Additional CSS for a specific page
{% block content %} Main page content
{% block extra_js %} JS for a specific page

Child Template: Article List

{# templates/blog/post_list.html #}
{% extends 'base.html' %}

{% block title %}Articles — DevBlog{% endblock %}

{% block content %}
  <h1>All Articles</h1>
  <div class="row g-4">
    {% for post in posts %}
      <div class="col-12 col-md-6 col-lg-4">
        <div class="card h-100">
          <div class="card-body">
            <h5 class="card-title">
              <a href="{% url 'post-detail' slug=post.slug %}">{{ post.title }}</a>
            </h5>
            <p class="card-text text-muted">{{ post.summary }}</p>
          </div>
        </div>
      </div>
    {% endfor %}
  </div>
{% endblock %}

Child Template: Article Page

{# templates/blog/post_detail.html #}
{% extends 'base.html' %}
{% load static %}

{% block title %}{{ post.title }} — DevBlog{% endblock %}

{% block extra_css %}
  <link rel="stylesheet" href="{% static 'css/highlight.css' %}">
{% endblock %}

{% block content %}
  <article>
    <h1>{{ post.title }}</h1>
    <p class="text-muted">{{ post.published_at|date:"F j, Y" }}</p>
    <div class="post-body">
      {{ post.body|safe }}
    </div>
  </article>
{% endblock %}

{% block extra_js %}
  <script src="{% static 'js/highlight.js' %}"></script>
{% endblock %}

{{ block.super }} — Extending a Block

{{ block.super }} inserts the parent block’s content without replacing it:

{# In a child template: #}
{% block title %}{{ post.title }} — {{ block.super }}{% endblock %}
{# Result: «Introduction to Python — DevBlog» #}

Useful for blocks containing navigation or scripts when you want to add to the existing content rather than replace it.

Inheritance Chains

You can build chains: base.htmlbase_blog.htmlpost_detail.html. More than two or three levels makes the code hard to follow — keep it reasonable.

base.html
  └── blog/base_blog.html  (adds a sidebar)
        ├── post_list.html
        └── post_detail.html

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

pytest-django: Testing Django

Охватываемые темы: Installation, @pytest.mark.djangodb, Fixtures, Testing views.

📅 30.06.2026 👁️ 138
📝

Django: Template Tags

Template tags are logic inside HTML. Unlike {{ variable }} which only outputs a value,...

📅 30.06.2026 👁️ 85
📝

Colors and Fonts in CSS

The first thing a DevBlog reader sees is text. Well-chosen colors and fonts make a...

📅 30.06.2026 👁️ 81

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!