Photo by Pankaj Patel on Unsplash
How to Structure Your Django Template The Right Way
When it comes to building web applications using Django, effective template structuring is crucial for creating maintainable and scalable code.
Introduction
Templates play a vital role in Django's MVT (Model-View-Template) structure. In simple terms, a Django template is like a particular HTML file written in languages like HTML, CSS, and Javascript. These templates create the visual appearance of web pages that users see on a Django-powered website.
Think of templates as a way to give your website a design and structure. While Django mainly focuses on handling behind-the-scenes functionality (backend), templates allow you to create the frontend part of your website. They help in organizing and generating the HTML content that gets displayed to the users.
This article includes the following topics:
Overview - Provide a basic overview of templates and explain their functioning.
Structure of template folders - Differentiating between project-level templates and app-level templates.
What You Need to Have
Basic knowledge of the Django framework.
Understanding of how to render a template from views(Optional).
If possible, a project to practice as you read along.
Overview
In Django, a template is a file that contains the structure and presentation logic of a web page. It defines how the data should be displayed to the user. Templates in Django use a combination of HTML markup and Django's template language, which allows you to dynamically generate content based on variables, perform loops, conditionals, and more.
Functioning of Templates in Django:
Template Rendering: When a request is made to a Django web application, the framework determines which view function should handle the request. The view function then gathers the necessary data and passes it to a template for rendering. The template receives the data and generates the final HTML output.
from django.shortcuts import render def my_view(request): # Data retrieved from a database or any other source user_name = "My friend" user_age = 25 user_email = "hellofriend.com" context = { 'name': user_name, 'age': user_age, 'email': user_email } return render(request, 'my_template.html', context)
Django Template Language (DTL): The Django template language provides a set of tags, filters, and variables that allow you to perform logic within your templates. Tags are enclosed within
{% ... %}
and are used for executing control structures like loops and conditionals. Filters, represented by|
, modify the data displayed in the template. Variables, enclosed within{{ ... }}
, display the data passed from the view.Context: The data that needs to be displayed in a template is passed to it in the form of a context. A context is a dictionary-like object containing variable names as keys and their corresponding values. The view function creates the context and passes it along with the template during rendering. Here is an example following the view above.
<h1>Welcome, {{ name }}!</h1> <p>Age: {{ age }}</p> <p>Email: {{ email }}</p>
Template Inheritance: Django templates support inheritance, allowing you to define a base template that can be extended by other templates. The base template contains the common structure and layout, while the child templates can override specific sections or add additional content.
base.html
<!DOCTYPE html> <html> <head> <title>{% block title %}{% endblock %}</title> </head> <body> <header> <!-- Common header content here --> </header> <nav> <!-- Common navigation content here --> </nav> <main> {% block content %} {% endblock %} </main> <footer> <!-- Common footer content here --> </footer> </body> </html>
{% extends 'base.html' %} {% block title %}Child Template{% endblock %} {% block content %} <!-- Specific content for this child template --> {% endblock %}
Static and Dynamic Content: Templates can display both static content (such as text, images, and links) and dynamic content (data retrieved from the database or processed by the view). The template engine combines these elements to generate the final HTML that is sent back to the client.
Structure of Template Folder
In Django, you have two primary options for organizing your template structure: the default method at the app level and a custom approach at the project level.
Option 1: App-level method
By default, the Django template loader searches for a "templates" folder within each app. However, to prevent namespace conflicts, you also need to create a subfolder with the app name within the "templates" folder before adding your template file. This approach is more suitable for smaller projects.
Assuming you are creating a profile app for your project, here is an example of how it should look in your project.
├── project_name
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
| └── profile
| ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
| ├── templates
| ├── profile
| ├── base.html
| |-- child.html
└── manage.py
When you add your templates at the app level, you do not need to specify them in the template section in settings. It is set to True.
# settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True, # here it is
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Option 2: Project-level method
As your Django project grows larger, it can become difficult to manage templates scattered across multiple apps. To make things more organized, you can store all your templates in one central location. Here's how you can achieve this:
Create a main folder for your templates: In your project's root directory, create a folder called "templates" (if it doesn't already exist). This folder will serve as the central location for all your templates.
Create separate folders for each app's templates: Within the "templates" folder, create a separate subfolder for each app in your project. For example, if you have an app called "profile", create a folder named "profile" within the "templates" folder.
├── project_name
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
| └── profile
| ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── templates
| ├── profile
| ├── base.html
| ├── child.html
└── manage.py
Note: if you add your templates at the project level, you need to update it in the settings.py file.
- Update your project's settings: Open the
settings.py
file located in your project's root directory. Look for theTEMPLATES
configuration option, which is a list of dictionaries. Inside the first dictionary (usually denoted by the'BACKEND'
key), add these lines of codeos.path.join(BASE_DIR, 'templates')
in theDIRS
. This tells Django to automatically search for templates within each app.
# settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # Here it is
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Conclusion:
Templates are essential in Django as they help you create the look and feel of your website by using HTML, CSS, and Javascript code. They bridge the gap between the back and front end, enabling you to provide an engaging user experience.
Drop feedback in the comment