Django Template System
Learn Django's template system for creating dynamic HTML pages with template inheritance. This is a foundational concept in Python web development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world Python/Django experience. Take your time with each section and practice the examples
Template Basics
Django templates are HTML files with special template syntax that allows you to dynamically generate content. Templates separate presentation logic from business logic.. This is an essential concept that every Python/Django developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Template Examples
<!-- base.html (Base template) -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My Blog{% endblock %}</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
<header>
<nav>
<a href="{% url 'home' %}">Home</a>
<a href="{% url 'post_list' %}">Blog</a>
<a href="{% url 'about' %}">About</a>
<a href="{% url 'contact' %}">Contact</a>
</nav>
</header>
<main>
{% block content %}
{% endblock %}
</main>
<footer>
<p>© 2024 My Blog. All rights reserved.</p>
</footer>
</body>
</html>
<!-- post_list.html (Extends base template) -->
{% extends 'base.html' %}
{% load static %}
{% block title %}Blog Posts{% endblock %}
{% block content %}
<div class="container">
<h1>Blog Posts</h1>
{% if posts %}
<div class="posts-grid">
{% for post in posts %}
<article class="post-card">
<h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></h2>
<p class="meta">
By {{ post.author.username }} |
{{ post.published_date | date:"F j, Y" }}
</p>
<p>{{ post.content | truncatewords:30 }}</p>
{% if post.category %}
<span class="category">{{ post.category.name }}</span>
{% endif %}
</article>
{% empty %}
<p>No posts available.</p>
{% endfor %}
</div>
<!-- Pagination -->
{% if is_paginated %}
<div class="pagination">
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">« Previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">Next »</a>
{% endif %}
</div>
{% endif %}
{% else %}
<p>No posts found.</p>
{% endif %}
</div>
{% endblock %}
<!-- post_detail.html -->
{% extends 'base.html' %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<article class="post-detail">
<header>
<h1>{{ post.title }}</h1>
<div class="meta">
<p>By {{ post.author.username }} | {{ post.published_date | date:"F j, Y" }}</p>
{% if post.category %}
<p>Category: <a href="{% url 'category_posts' post.category.slug %}">{{ post.category.name }}</a></p>
{% endif %}
</div>
</header>
<div class="content">
{{ post.content | linebreaks }}
</div>
{% if user == post.author %}
<div class="actions">
<a href="{% url 'post_update' post.pk %}" class="btn btn-edit">Edit</a>
<a href="{% url 'post_delete' post.pk %}" class="btn btn-delete">Delete</a>
</div>
{% endif %}
</article>
{% endblock %}