Stringly typed
Problem with django templates, and many other templates, is that we have to use strings to do some mini logic. In this todo we have to check against string ‘Done’ and ‘Not done’ status to show different text in button. Also there is lot of code compared to react’s ternary condition.
Model:
from django.db import models
class Todo(models.Model):
STATUS_CHOICES = [("Done", "Done"), ("Not Done", "Not Done")]
title = models.CharField(max_length=20)
status = models.TextField(choices=STATUS_CHOICES, default="Not Done")
Template:
<button>
{% if todo.status == 'Done' %} Mark not done {% elif todo.status == 'Not Done'
%} Mark done {% endif %}
</button>
I guess we can use some property methods on django model, but then what’s up with that too much boilerplate that many people like to say.
We can maybe use boolean instead of status Done and Not Done. Ok, but I don’t think that’s scalable, boolean here boolean there boolean soup everywhere. Use status.
Enumeration type choice
The way to somewhat mitigate this is to use enumeration type choice:
from django.db import models
class Todo(models.Model):
class Status(models.TextChoices):
DONE = "Done", "Done"
NOT_DONE = "Not Done", "Not Done"
title = models.CharField(max_length=20)
status = models.TextField(choices=Status.choices, default=Status.NOT_DONE)
Then in template we can use it like this:
<button>
{% if todo.status == todo.Status.DONE %} Mark not done {% elif todo.status ==
todo.Status.NOT_DONE %} Mark done {% endif %}
</button>
Now maybe PyCharm will provide intellisense, I am not sure.
Template Filter
If you repeat this often use template filter.
Filter:
from django import template
from todoist.models import Todo
register = template.Library()
@register.filter
def toggle_status_label(status):
if status == Todo.Status.DONE:
return "Mark not Done"
elif status == Todo.Status.NOT_DONE:
return "Mark Done"
Template:
{% load todo_filters %}
<!-- some code in between -->
<button>{{todo.status|toggle_status_label}}</button>
Errors
Good thing about Django is it has best error reports I’ve seen so far.
If you misspell the work like I did:
{% load todo_filter %}
It will show nice error:

Conclusion
All in all, django template is ok if you do almost nothing of logic. Little bit of logic becomes tedious. I think they should upgrade, it’s not 2006 anymore.