100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Django Templates

Learn Django's built-in template language — variables, tags, filters, template inheritance, and how the template engine renders context into HTML safely.

Views & URLsBeginner9 min readJul 10, 2026
Analogies

Rendering Templates with the Django Template Language

Django's template engine (DTL) renders .html files that mix static markup with {{ variable }} output and {% tag %} logic, evaluated against a context dictionary passed from a view via render(). Variables use dot notation that Django tries as dictionary lookup, then attribute lookup, then list-index lookup, then method call, in that order, stopping at the first that succeeds — so {{ article.author.name }} can traverse a model relationship without any template-side type-checking. By default, all variable output is auto-escaped, converting characters like < and & into HTML entities to prevent cross-site scripting unless explicitly marked safe.

🏏

Cricket analogy: It's like a scorecard broadcast graphic that pulls {{ batsman.name }} and auto-formats it safely for the on-screen overlay, trying player-object lookup, then a fallback dictionary, without the broadcast crew hand-coding each name's markup.

Tags and Filters

Template tags like {% if %}, {% for %}, and {% with %} provide control flow, while filters transform a variable's output using pipe syntax, such as {{ price|floatformat:2 }} or {{ name|upper }}, and can be chained: {{ text|truncatewords:30|linebreaks }}. Django ships dozens of built-in filters (date, default, length, slugify, pluralize) covering common formatting needs, and you can register custom filters and tags in a templatetags module inside an app when built-ins don't cover a domain-specific need, such as formatting a currency value per-locale.

🏏

Cricket analogy: It's like a scorecard's run-rate filter piping raw ball-by-ball data through a formatting function to display 'CRR: 8.45' instead of a raw unformatted float.

django
{# templates/articles/list.html #}
{% extends 'base.html' %}
{% load humanize %}

{% block content %}
  <h1>Latest Articles</h1>
  {% for article in articles %}
    <article>
      <h2><a href="{% url 'blog:post_detail' post_slug=article.slug %}">{{ article.title }}</a></h2>
      <p>{{ article.summary|truncatewords:30 }}</p>
      <small>{{ article.created_at|naturaltime }} by {{ article.author.get_full_name|default:'Unknown' }}</small>
    </article>
  {% empty %}
    <p>No articles published yet.</p>
  {% endfor %}
{% endblock %}

Template Inheritance and Includes

Template inheritance lets a base.html define the overall page skeleton with {% block %} placeholders (e.g., {% block content %}{% endblock %}), and child templates use {% extends 'base.html' %} at the very top of the file to override specific blocks while inheriting everything else, avoiding duplicated <head>, navigation, and footer markup across every page. {% include 'partial.html' %} is the complementary tool for reusable fragments that don't need the parent-child override relationship, such as a comment widget dropped into several unrelated pages, and it can pass extra context with {% include 'card.html' with item=product %}. The TEMPLATES setting's APP_DIRS option controls whether Django also searches each installed app's own templates/ directory, which is how reusable apps ship their own default templates that a project can still override by placing a same-named template earlier in its own TEMPLATES DIRS search path.

🏏

Cricket analogy: It's like a domestic league's standard match-day format (base.html) that every franchise (child template) follows, only swapping in team-specific elements like the anthem block, while the toss and innings structure stay inherited.

The {% extends %} tag must be the very first non-comment line in a child template — any tag or output placed before it is a common source of silent template rendering bugs where the extension appears to be ignored.

Never wrap untrusted user input in |safe or mark_safe() just to avoid escaping-related layout issues; doing so disables Django's automatic HTML escaping for that value and opens a direct cross-site scripting vulnerability.

  • DTL variables resolve via dict lookup, then attribute, then list-index, then method call, stopping at the first success.
  • Output is auto-escaped by default; use |safe or mark_safe() only for trusted, sanitized content.
  • Tags ({% if %}, {% for %}, {% with %}) provide control flow; filters transform output and can be chained with |.
  • Custom filters/tags live in an app's templatetags module and are loaded with {% load %}.
  • {% extends %} plus {% block %} implements template inheritance; it must be the first line in the child template.
  • {% include %} inserts reusable fragments and can pass extra context via the with clause.
  • APP_DIRS and TEMPLATES DIRS settings control where Django searches for templates, including app-shipped defaults.

Practice what you learned

Was this page helpful?

Topics covered

#Python#DjangoStudyNotes#WebDevelopment#DjangoTemplates#Django#Templates#Rendering#Template#StudyNotes#SkillVeris