Opened 20 years ago

Closed 20 years ago

Last modified 17 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: no UI/UX: no

Description

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:

<html>
  <head>
    <title>ifequal bug</title>
  </head>
  <body>
    <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>

    <h1>ifnotequal</h1>
    <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>

  </body>
</html>

and the output:

ifequal bug

1 2 3 4

1 2 3 4.

ifnotequal

,1 ,2 ,3 ,4

1 ,2 ,3 ,4

Change History (3)

comment:1 by Malcolm Tredinnick, 20 years ago

Resolution: → wontfix
Status: new → 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 by Malcolm Tredinnick, 20 years ago

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

comment:3 by sgornick, 17 years ago

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