Skip to main content

Django Templates Introduction

What are Django Templates?

Django templates are a powerful way to generate HTML dynamically. They form an essential part of Django's MVT (Model-View-Template) architecture, serving as the presentation layer of your web application. Templates allow you to separate the design of your pages from the Python code that powers your application.

At their core, Django templates are text files that can generate any text-based format like HTML, XML, CSV, etc. They contain static content as well as special syntax that describes how dynamic content will be inserted.

Why Use Templates?

Before diving into templates, let's understand why they're important:

  1. Separation of Concerns: Templates separate HTML/presentation from Python business logic
  2. Code Reusability: Common elements like headers and footers can be reused across multiple pages
  3. Designer-Developer Workflow: Designers can work on templates while developers focus on Python code
  4. Security: Django's template system automatically escapes variables to prevent XSS attacks

Template Basics

A Django template is essentially an HTML file with additional template tags and variables. Let's look at a simple example:

html
<!DOCTYPE html>
<html>
<head>
<title>{{ page_title }}</title>
</head>
<body>
<h1>Welcome to {{ site_name }}</h1>
<p>Hello, {{ user_name }}!</p>
</body>
</html>

In this example, {{ page_title }}, {{ site_name }}, and {{ user_name }} are variables that will be replaced with actual values when the template is rendered.

Template Configuration

Django automatically looks for templates in your app's templates directory. To set up templates:

  1. Create a templates folder in your Django app directory
  2. Inside that folder, create another folder with the same name as your app (this prevents namespace collisions)
  3. Place your HTML templates inside this folder

For example, for an app named blog, your structure would look like:

blog/
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── templates/
│ └── blog/
│ ├── index.html
│ └── post_detail.html
├── tests.py
├── urls.py
└── views.py

Rendering Templates

To render a template from a view, you'll use the render() function. Here's a basic view that renders a template:

python
from django.shortcuts import render

def home_view(request):
context = {
'page_title': 'Home Page',
'site_name': 'My Awesome Website',
'user_name': 'John Doe'
}
return render(request, 'myapp/home.html', context)

The render() function takes three arguments:

  • The request object
  • The path to the template
  • A dictionary (context) containing the data you want to pass to the template

When this view is executed, it will render the home.html template with the variables from the context dictionary.

Template Variables

As we've seen, you can pass variables to templates using the context dictionary. To use these variables in your template, you enclose them in double curly braces:

html
<h1>{{ variable_name }}</h1>

You can also access attributes of variables using dot notation:

html
<p>Author: {{ post.author }}</p>
<p>Published: {{ post.date_published }}</p>

Template Tags

Django templates also include template tags, which provide programming-like functionality within your templates. Template tags are enclosed in {% %} brackets.

Here are some common template tags:

For Loops

html
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>

If Statements

html
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}!</p>
{% else %}
<p>Please log in.</p>
{% endif %}

URL Tag

html
<a href="{% url 'post_detail' post.id %}">Read more</a>

Template Filters

Filters transform variable values before displaying them. They're applied using a pipe (|) character:

html
<p>Posted {{ post.date|date:"F j, Y" }}</p>
<p>{{ post.content|truncatewords:50 }}</p>

Common filters include:

  • lower: Converts text to lowercase
  • upper: Converts text to uppercase
  • length: Returns the length of a string or list
  • date: Formats a date according to a specified format
  • truncatewords: Truncates a string after a certain number of words

Template Inheritance

One of the most powerful features of Django's template system is template inheritance. It allows you to build a base template containing common elements and then extend it in child templates.

Base Template (base.html)

html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Site{% endblock %}</title>
<link rel="stylesheet" href="/static/css/main.css">
</head>
<body>
<header>
<h1>My Website</h1>
<nav>
<a href="/">Home</a>
<a href="/about/">About</a>
<a href="/contact/">Contact</a>
</nav>
</header>

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

<footer>
<p>&copy; 2023 My Website</p>
</footer>
</body>
</html>

Child Template (home.html)

html
{% extends "myapp/base.html" %}

{% block title %}Home | My Site{% endblock %}

{% block content %}
<h2>Welcome to the homepage!</h2>
<p>This is the content specific to the home page.</p>
{% endblock %}

In this example:

  • The {% extends %} tag specifies which template to inherit from
  • The {% block %} and {% endblock %} tags define sections that can be overridden in child templates
  • The child template only needs to define the content that's different from the base template

Practical Example: A Blog Post List

Let's put everything together to create a simple blog post listing page:

models.py:

python
from django.db import models

class BlogPost(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
content = models.TextField()
published_date = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.title

views.py:

python
from django.shortcuts import render
from .models import BlogPost

def post_list(request):
posts = BlogPost.objects.all().order_by('-published_date')
return render(request, 'blog/post_list.html', {'posts': posts})

post_list.html:

html
{% extends "blog/base.html" %}

{% block title %}Blog Posts | My Site{% endblock %}

{% block content %}
<h2>Latest Blog Posts</h2>

{% if posts %}
{% for post in posts %}
<article class="post">
<h3>{{ post.title }}</h3>
<p class="meta">By {{ post.author }} on {{ post.published_date|date:"F j, Y" }}</p>
<div class="content">
{{ post.content|truncatewords:30 }}
</div>
<a href="{% url 'post_detail' post.id %}">Read more</a>
</article>
{% endfor %}
{% else %}
<p>No posts available.</p>
{% endif %}
{% endblock %}

This example shows:

  1. A model to store blog posts
  2. A view that fetches posts and passes them to a template
  3. A template that displays the posts with formatting and filters

Summary

Django templates provide a powerful and flexible way to generate HTML content dynamically. They allow you to:

  • Separate your presentation logic from business logic
  • Pass data from views to templates using context dictionaries
  • Use variables, filters, and tags to manipulate and display data
  • Create reusable layouts through template inheritance
  • Build complex web interfaces with minimal repetition

As you grow more familiar with Django's template system, you'll find it makes building complex web applications much more manageable and maintainable.

Additional Resources

Practice Exercises

  1. Create a base template for a personal portfolio site with headers and footers
  2. Build a template that displays a list of products with prices and apply filters to format the prices
  3. Create a template that uses conditional tags to display different content based on user authentication status
  4. Build a blog post detail page that extends your base template
  5. Experiment with using custom template tags and filters

By mastering Django templates, you'll be able to create sophisticated web interfaces while maintaining clean, organized code.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)