На собеседованиях часто приходиться спрашивать и слышать про шаблоны Django как узкое место фреймворка. И в большинстве случаев мы говорим про скорость выполнения, недостаточную гибкость и простоту при создании кастомных фильтров или тегов.
Но сегодняшний инцидент стоит просто за гранью моего понимания. Итак, есть модель с полем NullBooleanField
, назовем его verified
. Далее в шаблоне нужно отображать специфический класс для HTML-тега если verified is False
. Что ж, это просто, за неимением is
возпользуюсь проверенным ==
:
<div{% if verified == False %} class="ui-state-error-text"{% endif %}> Some text Some input </div>
Ок, обновляю страницу и думаю все ок. Однако, не тут-то было. Результата нет, в исходном тексте тоже никакого class="ui-state-error-text"
нет и в помине. Странно. Ладно, дай думаю проверю в shell_plus
. Проверка подтверждает мои опасения:
In [2]: t = Template('{% if verified == False %}False{% else %}Not False{% endif %}')
In [3]: t.render(Context({'verified': False}))
Out[3]: u'Not False'
In [4]: t.render(Context({'verified': True}))
Out[4]: u'Not False'
In [5]: t.render(Context({'verified': None}))
Out[5]: u'False'
Хм, ясное дело свитч на {% if not verified %}
не достиг никаких результатов (теперь класс будет печататься и в случае, когда verified is None
):
In [6]: t = Template('{% if not verified %}False{% else %}Not False{% endif %}')
In [7]: t.render(Context({'verified': False}))
Out[7]: u'False'
In [8]: t.render(Context({'verified': True}))
Out[8]: u'Not False'
In [9]: t.render(Context({'verified': None}))
Out[9]: u'False'
Хм, что же делать? Как же быть? Почему {% if verified == None %}
работает если verified is None
. Спросил совета у команды. И надо сказать их совет подействовал, надо просто проверку на False
сменить на проверку на 0
. И все начинает работать:
In [10]: t = Template('{% if verified == 0 %}False{% else %}Not False{% endif %}')
In [11]: t.render(Context({'verified': False}))
Out[11]: u'False'
In [12]: t.render(Context({'verified': True}))
Out[12]: u'Not False'
In [13]: t.render(Context({'verified': None}))
Out[13]: u'Not False'
Теперь вопрос, что заставило Django-девов не добавить boolean константы True
и False
в {% if %}
темплейт тег? Где поддержка var is (None|True|False)
? Уже ж сделали вроде как вменяемый if
, что помешало сделать это раз и навсегда? Особенно в свете того, что поддержка конструкций item in list
и item not in list
была добавлена.
В целом был разочарован я изрядно, но теперь буду помнить, что для проверки на True
, False
в шаблонах надо сравнивать с 1
и 0
. Прям как хрен знает где еще :(