Custom template filter to return type not work as expected

I made custom template filter to check type of object.
I thought it will pass only the name of type like ‘int’ or ‘str’.
But it’s not working like that.

  • Information
    the schedules in the template contains one integer and 7 objects from my Schedule model

templatetags/get_type.py

from django import template

register = template.Library()


@register.filter
def get_type(object):
    return type(object)

Template HTML

<!DOCTYPE html>
{% extends "main/base.html" %}
{% load static %}
{% load get_type %}
{% block content %}
    <table class="table">
        <thead>
            <tr>
                <th scope="col">Period</th>
                {% for date in dates_of_week %}
                    <th scope="col">{{ date|date:"Y m d D" }}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            {% for object in object_list %}
                <tr>
                    {% for schedules in object %}
                        {% if schedules|get_type == "int" %}
                            <th scope="row">{{ schedules }}</td>
                        {% else %}
                            <td>{{ schedules.user }}</td>
                        {% endif %}
                    {% endfor %}
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

So this template doesn’t work like what I expected, but if I change {% if schedules|get_type == "int" %} to {% if schedules|get_type == 1|get_type %}, of course it works well.
I want this work as what I expect.
Can you tell me how to fix this?

Try out the equivalent code on the shell:

>>> x = 1
>>> type(x)
<class 'int'>
>>> type(x) == int
True
>>> type(x) == "int"
False

Notice these last two comparisons. The first compares the type of x with the int class. The second compares the type of x with the string "int". Types are never equal to strings, so the second form will never be true, no matter the type and string.

Your template comparison schedules|get_type == "int" is equivalent to the second form, hence it will never pass.

The form schedules|get_type == 1|get_type is equivalent to:

>>> type(x) == type(1)
True

… which is why it works.

Django’s template language is intentionally simple. It’s not possible to refer to the int type, so you can’t write schedules|get_type == int.

I would suggest instead implementing a specialized template filter that allows you to check if something is an int:

@register.filter
def is_int(object):
    return isinstance(object, int)

…and others for any further use cases you have.

Hope that helps!

Well…if that is the only solution, I should do that.
Thank you for answer.