Search code examples
pythondjangodjango-templatesdjango-custom-tags

Django template filter not registered after django dev server restart


I spent too much time trying to deal with the problem on my own, maybe someone here is able to help me. I am building a larger django app but removed everything except the code that highlights the problem.

I define two custom template tags:

edb/templatetags/edb_extra.py:

register = template.Library()

@register.inclusion_tag('edb/templatetags/event_tile.html')
def render_event_tile(event):
    return {'event':event}

@template.defaulttags.register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

with linked html edb/templatetags/event_tile.html:

<div>
    <h5> RENDER: {{ event.name }} </h5>
</div>

I serve the request through edb/views.py:

@login_required
def my_view(request):
    events = Event.objects.all()
    myevent = events[0]
    sorted_events = {'mykey': myevent}
    return render(request, "edb/using_tags.html", {'sorted_events':sorted_events, 'event':myevent})

and finally edb/using_tags.html:

{% load edb_extra %}

<!doctype html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <div class="main-panel">
            {% render_event_tile event %}
            {{ sorted_events|get_item:'mykey' }}
        </div>
    </body>
</html>

This code produces following error message when processed the first time after django dev server is restarted:

TemplateSyntaxError at en/edb/using_tags
Invalid filter: 'get_item'

When I hit the browser back button and repeat the request it works fine. It also works fine for all the subsequent requests until the server needs to be restarted (e.g. I change the view code).

Furthermore, if I remove {{ sorted_events|get_item:'mykey' }}, everything works fine from the very beginning so it seems that edb_extra.py is being correctly processed on time. But somehow inclusion_tag is being registered while filter is not.


Solution

  • Try to use the register template library in your decorator:

    @register.filter
    def get_item(dictionary, key):
        return dictionary.get(key)