Custom template tags in django
Tags: django, python
Published: 2023-02-07 16:25:53

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
```

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',
            ],
        },
    },
]
```

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"),
]
```

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")
```

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>
```

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
```

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
```

## 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
```

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}
```
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>
```
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>
```

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