In the previous Understand Django article, we looked at the fundamentals of using views in Django. This article will focus on templates. Templates are your primary tool in a Django project for generating a user interface. Let’s see how templates hook into views and what features Django provides with its template system.

Set Up Templates

We need a place for templates to live. Templates are static files that Django will fill in with data. In order to use those files, we must instruct Django on where to find them.

Like most parts of Django, this configuration is in your project’s settings file. After you use startproject, you can find a section in your settings file that will be called TEMPLATES. The section should look something like:

# project/settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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',
            ],
        },
    },
]

Django’s template system can use multiple template backends. The backends dictate how your templates will work. I would recommend sticking with the default Django template language. This language has the tightest integration with the framework and the strongest support.

The next thing to notice is APP_DIRS with its value of True. For the Django template language, setting this value to True will cause Django to look for template files within a templates directory in each Django application in your project. Note that this also includes any third party applications so you should probably leave this to True.

So, where should your templates go? There are different schools of thought in the Django community. Some developers believe in having all templates within applications. Others ascribe to having all your project’s templates in a single directory. I’m in this second category of developers. I find it valuable to keep all of the templates for my entire project within a single directory.

From my perspective, keeping templates in a single directory makes it very clear where all the layout and UI in your system will live. To use that pattern, we must set the DIRS variable with the directory that we want Django to include. I recommend keeping a templates directory at the root of your project. If you do that, your DIRS value will change to something like:

# project/settings.py

TEMPLATES = [
    ...
        "DIRS": [os.path.join(BASE_DIR, "templates")],
    ...
]

Finally, there is OPTIONS. Each backend can accept a variety of options. startproject set a number of context processors. We’ll come back to context processors later in this article.

With your templates set up, you’re ready to go!

Using Templates With Render

Django builds your user interface by rendering a template. The idea behind rendering is that dynamic data is combined with a static template file to produce a final output.

To produce an HttpResponse that contains rendered output, we use the render function. Let’s see an example.

# application/views.py

from django.shortcuts import render

def a_template_view(request):
    context = {'name': 'Johnny'}
    return render(request, 'hello.txt', context)

In this example, the view would use a template located in templates/hello.txt which could contain:

Hello {{ name }}

When this view responds to a request, a user would see “Hello Johnny” in their browser. There are some interesting things to note about this example.

  1. The template can be any plain text file type. Most often we will use HTML to make a user interface so you will often see some_template.html, but the Django template system can render on any type.
  2. In the process of rendering, Django took the context data dictionary and used its keys as variable names in the template. Because of special double curly brace syntax, the template backend swapped out {{ name }} for the literal value of “Johnny” that was in the context.

This idea of mixing context and static layout is the core concept of working with templates. The rest of this article builds on this root concept and shows what else is possible in the Django template language.

From the last article, you may recall seeing the TemplateView. In those examples, we provided a template name, and I declared that Django would take care of the rest. Now you can start to understand that Django takes the template name and calls code similar to render to provide an HttpResponse. Those examples were missing context data to combine with the template. A fuller example to replicate what is above would look like:

# application/views.py

from django.views.generic.base import TemplateView

class HelloView(TemplateView):
    template_name = 'hello.txt'

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['name'] = 'Johnny'
        return context

This example uses get_context_data so that we can insert our “dynamic” data into the rendering system to give us the response we want.

In a real application, a lot of the code that we need to write focuses on building up a truly dynamic context. I’m using static data in these examples to keep the mechanics of the template system clear. When you see me use context, try to imagine more complex data building to create a user interface.

Those are the fundamentals of rendering. We’ll now turn our attention to what the Django template language is capable of.

#user interfaces #django

Templates For User Interfaces · Matt Layman
1.15 GEEK