Template Engine Basics0%

Template Engine Basics

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Template Engine Basics

Django's built-in Django Template Language (DTL) is designed to balance power with ease of use. It bridges backend Python view logic and frontend HTML presentation. DTL enforces a strict separation of concerns: templates control presentation, while business logic remains in Python views and models.


1. DTL Syntax Building Blocks

Django templates use four primary syntactic constructs:

  1. 1
    Variables ({{ variable }}): Evaluates a variable from the context and outputs its string value.
  2. 2
    Tags ({% tag %}): Executes template logic, such as loops, conditional blocks, template inheritance, and URL resolution.
  3. 3
    Filters ({{ value|filter }}): Modifies variables prior to display (e.g. {{ title|title }}, {{ created_at|date:"M d, Y" }}).
  4. 4
    Comments ({# comment #}): Comments omitted from the final HTML output.

2. Template Variables & Dot Notation

DTL uses dot notation (.) to traverse objects, dictionaries, and methods:

DJANGO
{# Context passed from view: {"article": article_obj, "stats": {"likes": 42}} #}
 
<h1>{{ article.title }}</h1>
<p>Author: {{ article.author.get_full_name }}</p>
<span>Likes: {{ stats.likes }}</span>

Lookup Priority Order:

When evaluating foo.bar, Django tries in order:

  1. 1
    Dictionary lookup (foo['bar'])
  2. 2
    Attribute lookup (foo.bar)
  3. 3
    Method call (foo.bar()) - Note: methods that require arguments cannot be called in DTL!
  4. 4
    List-index lookup (foo[bar])

3. Core Template Tags

Conditional Blocks (if, elif, else)

DJANGO
{% if article.status == "published" %}
<span class="badge badge-success">Live</span>
{% elif article.status == "draft" %}
<span class="badge badge-warning">Draft Mode</span>
{% else %}
<span class="badge badge-secondary">Archived</span>
{% endif %}

Looping with for and empty

DJANGO
<div class="article-grid">
{% for article in articles %}
<article class="card">
<h2>{{ article.title }}</h2>
<p>{{ article.content|truncatewords:25 }}</p>
<small>Loop Index: {{ forloop.counter }} of {{ forloop.length }}</small>
</article>
{% empty %}
<p class="empty-state">No articles have been published yet.</p>
{% endfor %}
</div>

The {% empty %} block executes automatically if the list is empty or undefined, eliminating boilerplate {% if articles %} wrapping!


4. Useful Built-in Filters

  • |lower / |upper / |title: String case formatting.
  • |truncatewords:30: Truncates text after 30 words with ....
  • |date:"F j, Y, g:i a": Formats dates (e.g. "September 15, 2026, 4:45 am").
  • |default:"N/A": Fallback if variable is false, empty, or None.
  • |length: Returns the count of items in an array or string.

5. Reverse URL Resolution with {% url %}

Never hardcode relative URLs (/articles/5/) in HTML templates. Use the {% url %} tag to dynamically generate URLs from view names:

DJANGO
{# Resolves URL defined as path("<slug:slug>/", views.detail, name="detail") in articles app #}
<a href="{% url 'articles:detail' slug=article.slug %}">
Read Full Story
</a>

If you ever change your URL routing structure in urls.py, all template links update automatically without broken links!


Interactive Quiz

Practice Quiz

Question 1
What syntax does the Django Template Language use to output a variable value?
Question 2
What does the {% empty %} clause inside a {% for %} loop accomplish?
Question 3
Why can't you call Python methods that require arguments inside standard DTL templates (e.g. {{ article.calculate_cost(5) }})?
Question 4
What filter formats long text down to 20 words followed by an ellipsis?
Question 5
Why is using {% url 'articles:detail' slug=article.slug %} superior to writing href="/articles/{{ article.slug }}/"?
Next Lesson

Template Inheritance

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext