Chapter 3: Django Add Master Template

Django Add Master Template: How to create and use a proper master / base template (also called layout template, parent template, skeleton template…)

This is the file that appears on every single page of your site — header, navigation bar, footer, global CSS/JS links, meta tags, favicon, etc.

Right now many beginners either:

  • copy-paste the same <html><head><body> into every single template (DRY violation — nightmare to maintain)
  • or they skip it completely and end up with inconsistent design

We are going to fix that today — step by step, very carefully, so that your polls app (and any future apps) look professional and are easy to maintain for years.

Goal for Today

We want one single master template (base.html) that:

  • Contains all repeating parts (header, nav, footer, <head> tags…)
  • Lets every page extend it and only fill in the changing content
  • Supports page-specific title, extra CSS/JS, meta tags, body classes, etc.
  • Works with both function-based and class-based views
  • Is ready for static files (CSS, JS, images) — we’ll touch this lightly today

Step 1: Where Should base.html Live? (Two Popular Choices)

Location When to choose this Pros Cons
polls/templates/polls/base.html You have only one app right now Simple, everything in one app When you add second app → duplication
mysite/templates/base.html You plan to have multiple apps (recommended) Truly global — used by all apps Slightly more setup in settings

Recommendation for you right now (2026 best practice): Put it in the project-level templates/ folder → this is what almost every medium+ Django project does

Step 2: Create Project-Level Templates Folder

In your project root (next to manage.py):

Bash

Now your folder looks like:

text

Step 3: Tell Django to Look in Project-Level Templates

Open mysite/settings.py

Find the TEMPLATES setting (it’s a list with one big dict)

Make sure ‘DIRS’ includes your new folder:

Python

→ Now Django will look first in mysite/templates/, then in each app’s templates/

Step 4: Create the Master Template – base.html

Create mysite/templates/base.html

HTML

Step 5: Convert Existing Templates to Extend base.html

Open polls/templates/polls/index.html

Delete everything except the changing part and wrap it:

HTML

Do exactly the same for detail.html, results.html, etc.

Step 6: Quick Test

  1. Make sure you added ‘DIRS’: [BASE_DIR / ‘templates’] in settings
  2. Run python manage.py runserver
  3. Visit http://127.0.0.1:8000/polls/
  4. Check:
    • Header & footer appear
    • Title is correct
    • Clicking question → detail page also has same header/footer
    • Design is consistent

Common Gotchas & Fixes

Problem Likely Cause Fix
base.html not found Forgot to add DIRS in settings Add BASE_DIR / ‘templates’
Header/footer still missing Forgot {% extends “base.html” %} Add at very top of every child template
Title shows only default Forgot {% block title %} in child Add {% block title %}My Page{% endblock %}
CSS not applying Inline style conflict or missing block Put page-specific styles in {% block extra_head %}
current_year not available No context processor Add custom context processor (see earlier lesson)

Your Mini Task Right Now

  1. Create templates/base.html exactly as shown
  2. Update index.html and detail.html to extend it
  3. Add at least one extra block (e.g. {% block extra_head %} with a page-specific style)
  4. Visit both pages — enjoy the consistent look!

Tell me what you want next:

  • “Done! Now show me how to move CSS/JS to static files properly”
  • “How to make navbar show active link (current page highlight)?”
  • “I want to add Bootstrap 5 or Tailwind via CDN – example?”
  • “Got error TemplateDoesNotExist: base.html – help!”
  • Or finally: “Let’s add the voting form + POST handling + F() update”

You’ve just built the foundation that makes every future page 10× faster to create. Super proud of how far you’ve come — let’s keep this momentum! 🚀🇮🇳

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *