Mastering Django Template Architecture: A Step‑by‑Step Guide

This tutorial walks through designing Django templates to keep the UI organized and eliminate duplicate code by leveraging Django's template tags, inheritance, and includes, providing preparation steps, detailed examples of base.html, content inheritance, and reusable form components.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Mastering Django Template Architecture: A Step‑by‑Step Guide

In this tutorial we explain how to design Django templates to keep the UI organized and avoid code duplication, using Django’s built‑in template tags, inheritance and includes.

Preparation

Python 3.6

Django 2.2

AdminLTE 3.0.5

Step 1/4: base.html

Create a base.html that contains all common fragments such as the navigation bar, sidebar and footer.

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title>AdminLTE 3 | Starter</title>
  <link rel="stylesheet" href="{% static 'plugins/fontawesome-free/css/all.min.css' %}">
  <link rel="stylesheet" href="{% static 'dist/css/adminlte.min.css' %}">
  <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">
  <!-- Navbar -->
  <nav class="main-header navbar navbar-expand navbar-white navbar-light">
    <ul class="navbar-nav">
      <li class="nav-item"><a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a></li>
      <li class="nav-item d-none d-sm-inline-block"><a href="index3.html" class="nav-link">Home</a></li>
      <li class="nav-item d-none d-sm-inline-block"><a href="#" class="nav-link">Contact</a></li>
    </ul>
    <form class="form-inline ml-3">
      <div class="input-group input-group-sm">
        <input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">
        <div class="input-group-append"><button class="btn btn-navbar" type="submit"><i class="fas fa-search"></i></button></div>
      </div>
    </form>
    <ul class="navbar-nav ml-auto">
      <li class="nav-item dropdown"><a class="nav-link" data-toggle="dropdown" href="#"><i class="far fa-comments"></i><span class="badge badge-danger navbar-badge">3</span></a>
        <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
          <a href="#" class="dropdown-item">
            <div class="media">
              <img src="{% static 'dist/img/user1-128x128.jpg' %}" alt="User Avatar" class="img-size-50 mr-3 img-circle">
              <div class="media-body">
                <h3 class="dropdown-item-title">Brad Diesel<span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span></h3>
                <p class="text-sm">Call me whenever you can...</p>
                <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
              </div>
            </div>
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item">
            <div class="media">
              <img src="{% static 'dist/img/user8-128x128.jpg' %}" alt="User Avatar" class="img-size-50 img-circle mr-3">
              <div class="media-body">
                <h3 class="dropdown-item-title">John Pierce<span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span></h3>
                <p class="text-sm">I got your message bro</p>
                <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
              </div>
            </div>
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item">
            <div class="media">
              <img src="{% static 'dist/img/user3-128x128.jpg' %}" alt="User Avatar" class="img-size-50 img-circle mr-3">
              <div class="media-body">
                <h3 class="dropdown-item-title">Nora Silvester<span class="float-right text-sm text-warning"><i class="fas fa-star"></i></span></h3>
                <p class="text-sm">The subject goes here</p>
                <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
              </div>
            </div>
          </a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item dropdown-footer">See All Messages</a>
        </div>
      </li>
      <li class="nav-item dropdown"><a class="nav-link" data-toggle="dropdown" href="#"><i class="far fa-bell"></i><span class="badge badge-warning navbar-badge">15</span></a>
        <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
          <span class="dropdown-header">15 Notifications</span>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item"><i class="fas fa-envelope mr-2"></i> 4 new messages<span class="float-right text-muted text-sm">3 mins</span></a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item"><i class="fas fa-users mr-2"></i> 8 friend requests<span class="float-right text-muted text-sm">12 hours</span></a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item"><i class="fas fa-file mr-2"></i> 3 new reports<span class="float-right text-muted text-sm">2 days</span></a>
          <div class="dropdown-divider"></div>
          <a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>
        </div>
      </li>
      <li class="nav-item"><a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#" role="button"><i class="fas fa-th-large"></i></a></li>
    </ul>
  </nav>
  <!-- Main Sidebar Container -->
  <aside class="main-sidebar sidebar-dark-primary elevation-4">
    <a href="{% url 'home:landing' %}" class="brand-link"><img src="{% static 'dist/img/AdminLTELogo.png' %}" alt="AdminLTE Logo" class="brand-image img-circle elevation-3"><span class="brand-text font-weight-light">AdminLTE 3</span></a>
    <div class="sidebar">
      <div class="user-panel mt-3 pb-3 mb-3 d-flex">
        <div class="image"><img src="{% static 'dist/img/user2-160x160.jpg' %}" class="img-circle elevation-2" alt="User Image"></div>
        <div class="info"><a href="#" class="d-block">Alexander Pierce</a></div>
      </div>
      {% block sidebar %}{% endblock %}
    </div>
  </aside>
  {% block content_wrapper %}{% endblock %}
  <aside class="control-sidebar control-sidebar-dark"><div class="p-3"><h5>Title</h5><p>Sidebar content</p></div></aside>
  <footer class="main-footer"><div class="float-right d-none d-sm-inline">Anything you want</div><strong>Copyright © 2014-2019 <a href="https://adminlte.io">AdminLTE.io</a>.</strong> All rights reserved.</footer>
</div>
<script src="{% static 'plugins/jquery/jquery.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'dist/js/adminlte.min.js' %}"></script>
</body>
</html>

Step 2/4: Remove redundant common code

After creating base.html, the duplicated code in landing.html and home.html can be removed, leaving only page‑specific sections.

<div class="content-wrapper">
  <!-- Content Header (Page header) -->
  <div class="content-header">
    <div class="container-fluid">
      <div class="row mb-2">
        <div class="col-sm-6"><h1 class="m-0 text-dark">Polls Index Page</h1></div>
        <div class="col-sm-6"><ol class="breadcrumb float-sm-right"><li class="breadcrumb-item"><a href="#">Home</a></li><li class="breadcrumb-item active">Polls</li></ol></div>
      </div>
    </div>
  </div>
  <!-- Main content -->
  <div class="content">
    <div class="container-fluid">
      <div class="row">
        <div class="col-lg-6">
          <div class="card"><div class="card-body"><h5 class="card-title">Card title</h5><p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p><a href="#" class="card-link">Card link</a><a href="#" class="card-link">Another link</a></div></div>
          <div class="card card-primary card-outline"><div class="card-body"><h5 class="card-title">Card title</h5><p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p><a href="#" class="card-link">Card link</a><a href="#" class="card-link">Another link</a></div></div>
          <div class="card card-primary card-outline"><div class="card-header"><h3 class="card-title">General Elements</h3></div><div class="card-body">...form elements...</div></div>
        </div>
        <div class="col-lg-6">
          <div class="card"><div class="card-header"><h5 class="m-0">Featured</h5></div><div class="card-body"><h6 class="card-title">Special title treatment</h6><p class="card-text">With supporting text below as a natural lead‑in to additional content.</p><a href="#" class="btn btn-primary">Go somewhere</a></div></div>
        </div>
      </div>
    </div>
  </div>
</div>

Step 3/4: Inherit base.html

Declare base.html as the parent template with {% extends 'base.html' %} and wrap page‑specific markup inside the content_wrapper block.

{% extends 'base.html' %}
{% load static %}
{% block content_wrapper %}
  <div class="content-wrapper">
    ...page specific content...
  </div>
{% endblock %}

Step 4/4: Store common content separately

Create an advanced_forms folder and move the large form markup into general_elements_form.html, then include it where needed.

<form role="form">
  <div class="row">
    <div class="col-sm-6"><div class="form-group"><label>Text</label><input type="text" class="form-control" placeholder="Enter ..."></div></div>
    <div class="col-sm-6"><div class="form-group"><label>Text Disabled</label><input type="text" class="form-control" placeholder="Enter ..." disabled></div></div>
  </div>
  <div class="row">
    <div class="col-sm-6"><div class="form-group"><label>Textarea</label><textarea class="form-control" rows="3" placeholder="Enter ..."></textarea></div></div>
    <div class="col-sm-6"><div class="form-group"><label>Textarea Disabled</label><textarea class="form-control" rows="3" placeholder="Enter ..." disabled></textarea></div></div>
  </div>
  <div class="form-group"><label class="col-form-label" for="inputSuccess"><i class="fas fa-check"></i> Input with success</label><input type="text" class="form-control is-valid" id="inputSuccess" placeholder="Enter ..."></div>
  <div class="form-group"><label class="col-form-label" for="inputWarning"><i class="far fa-bell"></i> Input with warning</label><input type="text" class="form-control is-warning" id="inputWarning" placeholder="Enter ..."></div>
  <div class="form-group"><label class="col-form-label" for="inputError"><i class="far fa-times-circle"></i> Input with error</label><input type="text" class="form-control is-invalid" id="inputError" placeholder="Enter ..."></div>
  <div class="row">
    <div class="col-sm-6"><div class="form-group"><div class="form-check"><input class="form-check-input" type="checkbox"><label class="form-check-label">Checkbox</label></div></div></div>
    <div class="col-sm-6"><div class="form-group"><div class="form-check"><input class="form-check-input" type="radio" name="radio1"><label class="form-check-label">Radio</label></div></div></div>
  </div>
  <div class="row">
    <div class="col-sm-6"><div class="form-group"><label>Select</label><select class="form-control"><option>option 1</option><option>option 2</option></select></div></div>
    <div class="col-sm-6"><div class="form-group"><label>Select Disabled</label><select class="form-control" disabled><option>option 1</option></select></div></div>
  </div>
</form>

Finally, include the form with {% include 'advanced_forms/general_elements_form.html' %} in the desired templates.

By structuring templates this way, the project becomes easier to maintain and scales better, reinforcing the principle of avoiding duplicate code in both front‑end and back‑end development.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DjangoWeb DevelopmenttemplateAdminLTE
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.