What’s wrong with Django’s template system

Or “In doubt, use Jinja.”


(DISCLAIMER: I do not work for vidait, I just found their image on google and I thought it would be cool to provide the source because I’m a cool guy.)

While this is debatable, nowadays Django is the most important framework in the Python community. It would be like Ruby’s Rails or Javascript’s jQuery. Basically, you’ll see people loving it or hating it. While in my work I work mostly with pure Python and Flask, I finally got to stand face-to-face against a Django website that would (in some point) be launched to the masses.

The idea is simple: a shopping cart for events like concerts, theatre and other events. The code was made by a co-worker around a year ago and it faced me with two challenges: Refreshing my quite rusty Django knowledge and doing it in Python 3. Yeah, I know, I should already know Python 3 because Python 2 is deprecated, but I didn’t, know I do a bit more. Getting back to the point, the shopping cart was a bit (I’m being polite here) empty by the amount of time it took and because It’s just a shopping cart.

It took me at least an hour to get used to the structure and to be able to find what I wanted to edit easily, maybe another hour to understand the url and query semantic but the only thing I just could not stand was the template system. While Django truly is a complete system, I stand by the Armin Ronacher’s idea of a Flask:

The majority of web applications will need a template engine in some sort. However not every application needs a SQL database.

And this is true, not all web pages need databases but in one way or the other you’ll need a way to transfer raw data into some sort of way so the end-user can access to it. That’s why the template engine is a fundamental part of any framework, and in this, Django lacks a lot of work.


Django’s rules, not yours.

One of the things I really like about Jinja is that you can mix the template language with raw python. That means, you can avoid having to pre-process data in your views just to, for example, convert numbers into strings. I’m not saying I’m doing SQL queries inside a tag, but creating a custom tag to execute something simple as converting a number into string or vice versa goes against the whole motto of the framework.

Turning the simple into complicated

Let’s say I want to get x value of a list that loops through a template and then go to another part of the template and ask if the x value is null or if it contains a value. Django by default does not contain by default any way to set custom variables inside a template. It’s not a complicated tag, but in Django you can have several ways to achieve this and not all of them work the way you want to. On Jinja, on the other hand, you can have it as easy as {% set variable = True %} and use it like this {{ variable }}. You may see people use with in django, but this does not hold the same purpose:

Caches a complex variable under a simpler name. This is useful when accessing an “expensive” method (e.g., one that hits the database) multiple times.

So watch out how you use it.

The contrast

Sometimes, we might not see it but, in contrast, Django does make an incredible contrast with Jinja. For example:

URLs in Jinja2
{{ url_for(‘index’) }} # Invokes the url from the decorator in the function I’m calling. Simple. Easy. Effective.
URLs in Django
{% url ‘view.index’ %} # It works.That is, if you know exactly the view pattern and know which arguments you need to return.
Complex URLS in Jinja2
{{ url_for(‘function’, argument=’value’) }} # So when another programmer comes, he’ll know what function and which argument he needs to alter or use this url.
Complex URLS in Django
{% url ‘view.function’ argument %} # You don’t know which view from which app is calling and god knows what argument is expected to be passed, if the developer was kind enough to use a proper variable name convention.

Bottom Line

Django’s templating system needs work, and a lot of it, not to be simple but to be effective. This is one of the most important features a web framework has, the way it digests the data and how the developer is capable of working with it, and the Django community is forgetting about it.

Email me when Leandro Poblet publishes or recommends stories