Opened 12 years ago

Closed 12 years ago

Last modified 9 years ago

#2838 closed defect (wontfix)

ifequal and ifnotequal give unexpected results for True/False comparison

Reported by: micktwomey@… Owned by: Adrian Holovaty
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 12 years ago by Malcolm Tredinnick

Resolution: wontfix
Status: newclosed

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 12 years ago by Malcolm Tredinnick

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

comment:3 Changed 9 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