🎨 Django Templates: Your Website’s Coloring Book
Imagine you’re making a birthday party invitation. You have a blank template with spaces for the name, date, and place. You just fill in the blanks, and boom—a perfect invitation every time!
Django templates work the same way. They’re like coloring books for websites. The outline (template) stays the same, but you fill in different colors (data) to make each page unique.
🏠 Templates Configuration: Setting Up Your Art Studio
Before you can start coloring, you need to set up your art supplies. Django needs to know where your templates live.
The Settings Detective 🔍
In your settings.py, there’s a special list called TEMPLATES. Think of it as a treasure map that tells Django where to find your coloring pages.
TEMPLATES = [
{
'BACKEND': 'django.template
.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context
_processors.request',
],
},
},
]
What Each Part Means
| Setting | What It Does |
|---|---|
BACKEND |
The template engine (Django’s built-in) |
DIRS |
Folders where templates live |
APP_DIRS |
Look in each app’s templates/ folder |
OPTIONS |
Extra magic powers |
Quick Setup Example
my_project/
├── templates/ ← Global templates
│ └── base.html
├── myapp/
│ └── templates/ ← App templates
│ └── myapp/
│ └── home.html
Pro tip: Always create a subfolder with your app name inside templates/. This prevents name collisions!
👑 Template Inheritance: The Royal Family of Templates
Imagine a royal family. The King (base template) has certain features—a crown, a robe, a scepter. The Prince inherits everything from the King but can add his own sword or shield.
Template inheritance works exactly like this!
The King Template (base.html)
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}
My Site
{% endblock %}</title>
</head>
<body>
<nav>Navigation Bar</nav>
{% block content %}
<!-- Prince fills this in -->
{% endblock %}
<footer>© 2024 My Site</footer>
</body>
</html>
The Prince Template (home.html)
{% extends 'base.html' %}
{% block title %}Home Page{% endblock %}
{% block content %}
<h1>Welcome Home!</h1>
<p>This is my kingdom.</p>
{% endblock %}
The Magic Revealed
graph TD A[base.html] --> B[home.html] A --> C[about.html] A --> D[contact.html] B --> E[Inherits nav + footer] C --> E D --> E
Result: Every page gets the same nav and footer automatically. You only write them once!
🏷️ Template Inheritance Tags: The Magic Words
Three special words make inheritance work:
1. {% extends %} - “I want to be like you!”
Always the first line in a child template.
{% extends 'base.html' %}
2. {% block %} - “This part can change”
Creates a replaceable section.
{% block sidebar %}
<div>Default sidebar</div>
{% endblock %}
3. {% block.super %} - “Keep parent’s stuff too!”
Want to ADD to the parent instead of replacing?
Parent:
{% block styles %}
<link rel="stylesheet" href="main.css">
{% endblock %}
Child:
{% block styles %}
{{ block.super }}
<link rel="stylesheet" href="extra.css">
{% endblock %}
Result: Both CSS files load!
🔀 Control Flow Template Tags: The Traffic Lights
Just like traffic lights control cars, these tags control what shows up on your page.
{% if %} - The Yes/No Guard
{% if user.is_authenticated %}
<p>Hello, {{ user.username }}!</p>
{% else %}
<p>Please log in.</p>
{% endif %}
{% for %} - The Repeat Machine
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% empty %}
<li>No fruits today!</li>
{% endfor %}
</ul>
Special for Loop Variables
| Variable | What It Tells You |
|---|---|
forloop.counter |
Current loop (1, 2, 3…) |
forloop.first |
Is this the first item? |
forloop.last |
Is this the last item? |
{% with %} - The Nickname Maker
Give long names a short nickname:
{% with total=business.employees.count %}
<p>{{ total }} people work here.</p>
{% endwith %}
🔗 URL and Static Template Tags: The Address Book
{% url %} - Smart Links
Never hardcode URLs! Use names instead.
In urls.py:
path('profile/<int:id>/',
views.profile,
name='user_profile')
In template:
<a href="{% url 'user_profile' id=5 %}">
View Profile
</a>
Output: /profile/5/
{% static %} - Finding Your Files
For images, CSS, and JavaScript:
{% load static %}
<img src="{% static 'images/logo.png' %}">
<link href="{% static 'css/style.css' %}">
graph TD A[static folder] --> B[images/] A --> C[css/] A --> D[js/] B --> E[logo.png] C --> F[style.css] D --> G[app.js]
Remember: Always add {% load static %} at the top!
🛡️ CSRF Token Tag: The Secret Handshake
Imagine a secret club. Members have a special handshake to prove they belong. Without it, no entry!
CSRF tokens work the same way. They protect your forms from bad guys.
The Problem
Bad websites can trick your browser into submitting forms to your site. This is called Cross-Site Request Forgery (CSRF).
The Solution
<form method="POST">
{% csrf_token %}
<input type="text" name="message">
<button type="submit">Send</button>
</form>
What Happens Behind the Scenes
graph TD A[User Opens Form] --> B[Django adds secret token] B --> C[User Submits Form] C --> D{Token matches?} D -->|Yes| E[Accept form ✅] D -->|No| F[Reject form ❌]
The Golden Rules
- ✅ Always use
{% csrf_token %}in POST forms - ✅ Place it inside the
<form>tag - ❌ Never needed for GET forms
- ❌ Never share your token!
🎯 Putting It All Together
Here’s a complete template using everything we learned:
{% extends 'base.html' %}
{% load static %}
{% block title %}Products{% endblock %}
{% block content %}
<h1>Our Products</h1>
<form method="POST">
{% csrf_token %}
<input name="search"
placeholder="Search...">
</form>
{% if products %}
{% for product in products %}
<div class="product">
<img src="{% static 'img/product.png' %}">
<h2>{{ product.name }}</h2>
<a href="{% url 'detail' id=product.id %}">
View Details
</a>
{% if forloop.last %}
<p>That's all folks!</p>
{% endif %}
</div>
{% endfor %}
{% else %}
<p>No products yet!</p>
{% endif %}
{% endblock %}
🌟 Summary: Your Template Toolkit
| Tool | Purpose | Example |
|---|---|---|
TEMPLATES setting |
Configure where templates live | 'DIRS': [BASE_DIR / 'templates'] |
{% extends %} |
Inherit from parent | {% extends 'base.html' %} |
{% block %} |
Define replaceable sections | {% block content %}{% endblock %} |
{% if/else %} |
Show content conditionally | {% if user %}Hi!{% endif %} |
{% for %} |
Loop through items | {% for x in list %}{% endfor %} |
{% url %} |
Generate URLs by name | {% url 'home' %} |
{% static %} |
Link to static files | {% static 'css/style.css' %} |
{% csrf_token %} |
Protect forms | Inside POST forms |
🚀 You Did It!
You now understand Django templates like a pro:
- ✅ Configuration - Where templates live
- ✅ Inheritance - DRY (Don’t Repeat Yourself)
- ✅ Control Flow - If/else and loops
- ✅ URLs & Static - Smart linking
- ✅ CSRF Protection - Secure forms
Templates are your website’s backbone. Master them, and you can build anything!
Remember: Every expert was once a beginner. Keep practicing, keep building! 🎉