Django - Template System
Django - Template System
Section titled “Django - Template System”Django’s template system provides a powerful yet designer-friendly way to separate the presentation of a document (HTML) from its data (Python logic). It uses a mini-language, the Django Template Language (DTL), to embed logic and variables within HTML files.
The render Function
Section titled “The render Function”As seen in the Views chapter, the django.shortcuts.render function is commonly used to combine a template with a context dictionary and return an HttpResponse object.
from django.shortcuts import renderimport datetime
def current_datetime(request): now = datetime.datetime.now() context = {'current_date': now} return render(request, 'myapp/datetime.html', context)This function typically takes three arguments:
request: TheHttpRequestobject.template_name: The path to the template file (relative to directories specified in theTEMPLATESsetting insettings.py, often within an app’stemplatessubdirectory).context: A dictionary mapping variable names (keys) to their values. These variables become accessible within the template.
Django Template Language (DTL)
Section titled “Django Template Language (DTL)”DTL defines syntax for variables, tags, filters, and comments within your template files.
Variables ({{ variable }})
Section titled “Variables ({{ variable }})”Variables are surrounded by double curly braces: {{ variable }}. When the template engine encounters a variable, it evaluates it using the provided context and replaces the variable tag with the result.
Example: myapp/templates/myapp/datetime.html using the context from the view above:
<!DOCTYPE html><html><head><title>Current Time</title></head><body> <p>The current date and time is: {{ current_date }}</p></body></html>Output might look like: The current date and time is: Sept. 11, 2023, 4:01 p.m. (Django automatically formats datetime objects).
Dot Lookup: You can access attributes of variables using dot (.) notation, similar to Python. Django tries dictionary lookup, attribute lookup, and list-index lookup in that order.
Example: If current_date is a datetime object, {{ current_date.year }} would output the year.
Filters ({{ variable|filter }})
Section titled “Filters ({{ variable|filter }})”Filters modify variables for display. They are applied using a pipe (|) character.
Common Examples:
{{ user_bio|truncatewords:30 }}: Truncates the string to the first 30 words.{{ page_title|lower }}: Converts the string to lowercase.{{ item_list|length }}: Returns the length of the list.{{ article.publication_date|date:"Y-m-d" }}: Formats a date object (using PHP date format specifiers).{{ raw_html|safe }}: Marks a string as safe, preventing auto-escaping (use with caution!).{{ value|default:"N/A" }}: Provides a default value ifvalueis False or empty.
Filters can be chained: {{ my_text|escape|linebreaks }}.
Find more built-in filters: Django Built-in Filter Reference
Tags ({% tag %})
Section titled “Tags ({% tag %})”Tags provide logic within templates, such as loops, conditionals, template inheritance, loading external resources, and more. They are surrounded by {% and %}.
{% if %}, {% elif %}, {% else %}, {% endif %}
Section titled “{% if %}, {% elif %}, {% else %}, {% endif %}”Performs conditional logic.
{% if user.is_authenticated %} <p>Welcome, {{ user.username }}!</p>{% elif user.is_guest %} <p>Welcome, Guest!</p>{% else %} <p><a href="{% url 'login' %}">Log in</a></p>{% endif %}{% for %}, {% empty %}, {% endfor %}
Section titled “{% for %}, {% empty %}, {% endfor %}”Loops over items in a sequence (like a list or queryset). The optional {% empty %} block is rendered if the sequence is empty.
<ul>{% for item in item_list %} <li>{{ forloop.counter }}: {{ item.name }}</li>{% empty %} <li>No items available.</li>{% endfor %}</ul>The forloop variable provides information about the loop’s state (e.g., forloop.counter, forloop.first, forloop.last).
{% extends %} and {% block %} (Template Inheritance)
Section titled “{% extends %} and {% block %} (Template Inheritance)”This powerful feature allows you to create a base template skeleton containing common site elements, and child templates that override specific parts.
Base Template (myapp/templates/myapp/base.html):
<!DOCTYPE html><html><head> <title>{% block title %}My Site{% endblock %}</title> <!-- Common CSS/JS --></head><body> <header>Site Header</header> <main> {% block content %} <!-- Default content goes here --> {% endblock %} </main> <footer>Site Footer</footer></body></html>Child Template (myapp/templates/myapp/specific_page.html):
{% extends "myapp/base.html" %}
{% block title %}Specific Page Title{% endblock %}
{% block content %} <h2>Welcome to the Specific Page</h2> <p>This content overrides the base template's content block.</p>{% endblock %}The {% extends %} tag must be the first tag in the child template. It specifies the parent template. {% block %} tags define areas that child templates can override.
{% url %}
Section titled “{% url %}”Generates URLs based on the names defined in your urls.py. This avoids hardcoding URLs, making your application more maintainable.
<a href="{% url 'article-detail' article.id %}">Read More</a><form action="{% url 'search' %}" method="get">{% load %}
Section titled “{% load %}”Loads custom template tags and filters.
{% load static %}{% load humanize %}
<img src="{% static 'images/logo.png' %}" alt="Logo"><p>Value: {{ large_number|intcomma }}</p>{% static %} (requires {% load static %})
Section titled “{% static %} (requires {% load static %})”Generates the URL for static files (CSS, JavaScript, images) based on your STATIC_URL setting.
Comments
Section titled “Comments”Single-line comments: {# This is a template comment #}
Multi-line comments: {% comment %} ... comment text ... {% endcomment %}
These comments are not included in the final HTML output.
Further Reading: Django Template Language Documentation