Core Concepts

Templates

Build dynamic HTML pages with Django's powerful template language.

Django Template Language (DTL)

Django's template language lets you embed Python-like logic in HTML:

  • {{ variable }} — output a variable
  • {% tag %} — template tags for logic (if, for, block, etc.)
  • {{ value|filter }} — transform values with filters

Template Inheritance

Create a base template with blocks, then extend it in child templates. This is the key to DRY templates.

Template Tags

Built-in tags include:

  • {% for %} / {% endfor %}
  • {% if %} / {% elif %} / {% else %} / {% endif %}
  • {% block name %} / {% endblock %}
  • {% extends "base.html" %}
  • {% include "partial.html" %}
  • {% url 'view-name' arg %}
  • {% static 'file.css' %}

Example

python
{# templates/base.html #}
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My Blog{% endblock %}</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/main.css' %}">
</head>
<body>
    <nav>
        <a href="{% url 'post-list' %}">Blog</a>
        {% if user.is_authenticated %}
            <span>Hello, {{ user.username }}!</span>
            <a href="{% url 'logout' %}">Logout</a>
        {% else %}
            <a href="{% url 'login' %}">Login</a>
        {% endif %}
    </nav>

    <main>
        {% block content %}{% endblock %}
    </main>
</body>
</html>

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

{% block title %}Blog Posts{% endblock %}

{% block content %}
<h1>Latest Posts</h1>

{% if posts %}
    {% for post in posts %}
    <article>
        <h2><a href="{% url 'post-detail' post.slug %}">{{ post.title }}</a></h2>
        <p class="meta">
            By {{ post.author.username }} |
            {{ post.created_at|date:"F j, Y" }} |
            {{ post.category.name }}
        </p>
        <p>{{ post.excerpt|truncatewords:30 }}</p>
        <a href="{% url 'post-detail' post.slug %}">Read more &rarr;</a>
    </article>
    {% endfor %}

    {# Pagination #}
    {% if is_paginated %}
    <div class="pagination">
        {% if page_obj.has_previous %}
        <a href="?page={{ page_obj.previous_page_number }}">Previous</a>
        {% endif %}
        Page {{ page_obj.number }} of {{ page_obj.num_pages }}
        {% if page_obj.has_next %}
        <a href="?page={{ page_obj.next_page_number }}">Next</a>
        {% endif %}
    </div>
    {% endif %}
{% else %}
    <p>No posts yet.</p>
{% endif %}
{% endblock %}
Try it yourself — PYTHON