DEV Community

codewitgabi
codewitgabi

Posted on • Updated on

Custom template tags in django

Good day everyone!! So I was creating this project for a client and then I came upon a roadblock; I had to query the data base but it wouldn't work since model.objects.filter() won't work on HTML. So I had to create a custom tag for that and shocking, it is very easy to create.

I'll assume you already have knowledge on django so I won't be going over the basics.

Run the following commands on your command prompt or terminal to start a django project

$ mkdir CustomTags
$ cd CustomTags
$ django-admin startproject myproject .
$ python manage.py startapp myapp
$ mkdir templates
Enter fullscreen mode Exit fullscreen mode

Once you're done, go into your settings.py file in myproject directory to configure some settings.

INSTALLED_APPS = [
    ...
    myapp.apps.MyappConfig,
    # other apps
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR, "templates], # add this line
        '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',
            ],
        },
    },
]
Enter fullscreen mode Exit fullscreen mode

After adding these configurations, go into your project's urls.py file to configure url routing. This is a small project so we won't be creating urls.py file for our app.

from django.urls import path
from myapp import views

urlpatterns = [
    # other url paths
    path("", views.index, name="index"),
]
Enter fullscreen mode Exit fullscreen mode

Since we have a url for index and we don't have a view yet, let's create that in our app's views.py

from django.shortcuts import render

def index(request):
    return render(request, "index.html")
Enter fullscreen mode Exit fullscreen mode

Now that we have the view, let's create the template (index.html). Earlier on, we created a templates directory. Go into that directory and create a file named index.html and add the following code to it.

<html>
<body>
    <h2>Index Page</h2>
<body>
</html>
Enter fullscreen mode Exit fullscreen mode

This will do for now. Let's create a model that we will query using our custom template tag.

models.py

class Person(models.Model):
    name = models.CharField(max_lemgth=20)
    age = models.IntegerField(default=0)

    def __str__(self):
        return self.name
Enter fullscreen mode Exit fullscreen mode

After this, go into your command prompt or terminal on linux and run these commands

$ cd CustomTags && cd myproject
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py createsuperuser
Enter fullscreen mode Exit fullscreen mode

Creating the Template tags

We will be creating a simple tag to query our Person model using tag. I know this can be done directly but this is just to give you a head start when building complex tags.

creating templatetags directory

To create a template tag, you need to create a directory named templatetags in one of your apps and this app must be in INSTALLED_APPS.

So going into myapp directory, create a folder called templatetags. Go into the directory and create a init.py file and then the file where you'll create your custom tags. Therefore your directory should look like this

myapp
    templatetags
        __init__.py
        custom_tags.py
    views.py
Enter fullscreen mode Exit fullscreen mode

Once this is done, go into custom_tags.py and begin writing your tag.

Creating the tag function

This function should return a dictionary.

from django import template
register = template.Library()

@register.inclusion_tag("output.html")
def make_query(person):
    q = person.objects.filter(name__startswith="a").order_by("-age")
    return {"persons": q}
Enter fullscreen mode Exit fullscreen mode

You can see I added output.html! That file will be created by you to show how the output of your tag should look like

So create output.html and save it in the templates directory. Our output.html should look like this

<ul>
    {% for person in persons %}
        <li>{{ person }}</li>
    {% endfor %}
</ul>
Enter fullscreen mode Exit fullscreen mode

Our tag is completed. What is remaining is for us to use this tag in our HTML files.

Using custom tags

To use a custom tag, we need to register the name of the file in which our custom tags are written. So in our index.html, we need to add this at the top

{% load custom_tags %}
<html>
<body>
    <h2>Index Page</h2>
    {% make_query person %}
<body>
</html>
Enter fullscreen mode Exit fullscreen mode

With this, our custom tag has been successfully created. Thanks for reading.

Top comments (0)