Opened 9 years ago

Closed 9 years ago

Last modified 7 years ago

#2838 closed defect (wontfix)

ifequal and ifnotequal give unexpected results for True/False comparison

Reported by: micktwomey@… Owned by: adrian
Component: Template system Version:
Severity: normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


The ifequal and ifnotequal tags behave in an unexpected manner when comparing a variable against True or False. They never evaluate to true or false when comparing a variable against True or False. I think this happens when django.template.defaulttags.IfEqualNode tries to resolve True/False using django.template.resolve_variable and gets and exception, so it uses None for the comparison.

I know it's better to write if or if not tags in templates, but this kind of mistake could trip up beginners. One possible fix is to change resolve_variable so it knows about True and False, another would be to simply document this and recommend if/if not instead.

An example template with the problem:

    <title>ifequal bug</title>
    <h1>ifequal bug</h1>
    <p>{% for i in stuff %}
      {{i}}{% ifequal forloop.last True %}.{% endifequal %}
    {% endfor %}</p>
    <p>{% for i in stuff %}
      {{i}}{% if forloop.last %}.{% endif %}
    {% endfor %}</p>

    <p>{% for i in stuff %}
      {% ifnotequal forloop.first False %},{% endifnotequal %}{{i}}
    {% endfor %}</p>
    <p>{% for i in stuff %}
      {% if not forloop.first %},{% endif %}{{i}}
    {% endfor %}</p>


and the output:

ifequal bug

1 2 3 4

1 2 3 4.


,1 ,2 ,3 ,4

1 ,2 ,3 ,4

Change History (3)

comment:1 Changed 9 years ago by mtredinnick

  • Resolution set to wontfix
  • Status changed from new to closed

No, we don't want to do this (it was in very briefly and reverted in [3680]). Template tags know about two types of things: context variables (words without quotes) and strings (words in double quotes). Your wish is that it treats certain other words as reserved words, which just overloads things further.

See this thread on django-developers for an explanation of why we do things the current way.

comment:2 Changed 9 years ago by mtredinnick

I have updated the documentation to explain how to test against True and False in [3880].

comment:3 Changed 7 years ago by sgornick

Shouldn't an attempt to do this throw an exception then instead of executing it and providing an unexpected result?

Note: See TracTickets for help on using tickets.
Back to Top