Opened 13 years ago

Last modified 13 years ago

#17229 closed New feature

Allow 'True', 'False' and 'None' to resolve to corresponding Python objects — at Version 5

Reported by: anatoly techtonik <techtonik@…> Owned by: nobody
Component: Template system Version: 1.2
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description (last modified by Luke Plant)

[Original bug title: Invalid '==' expression silently ignored leading to invalid result]

Let me clarify the title - I am not sure the expression below is invalid. It is the expression I intuitively expect to work. But perhaps Django it is a specifics of template language. In any case it should either complain or produce expected output, which it doesn't.

_{{ closed }}_
{% if closed == True %} ***** {% endif %}

If closed variable is equal to None, the example above will output the string:

_None_ *****

Expected is to output nothing or to give a warning about invalid right-side argument.

If closed is boolean (not string) and is equal to True, it will output

_True_

Expected is to output

_True_ *****

or to give a warning about invalid right-side argument.

Change History (5)

comment:1 by Luke Plant, 13 years ago

Resolution: invalid
Status: newclosed

Your example is invalid, because 'True' is not a literal that is understood by the template language. Rather, the string 'True' in your template is interpreted as a variable name. Since a variable called "True" does not exist in the context, the behaviour you see above follows (though the full sequence of steps is a little involved).

The expression you want is simply:

{% if closed %}

If you want the negation:

{% if not closed %}

(This, by the way, is normally considered good style in Python as well. Adding the no-op comparison == True is pointless - and so neither the majority of Python developers nor template writers would intuitively write this).

comment:2 by Luke Plant, 13 years ago

By the way, the template language does not give warnings for missing variables. By design it succeeds silently, and on rare occasions throws exceptions.

in reply to:  1 comment:3 by anatoly techtonik <techtonik@…>, 13 years ago

Needs documentation: set
Resolution: invalid
Status: closedreopened

Replying to lukeplant:

Your example is invalid, because 'True' is not a literal that is understood by the template language.

This explains the behavior, but doesn't solve the issue.

Rather, the string 'True' in your template is interpreted as a variable name. Since a variable called "True" does not exist in the context, the behaviour you see above follows (though the full sequence of steps is a little involved).

Don't you think that Pythonic template engine should allow standard Python True/False keywords in comparison expressions? There is a clear need to use them for NullBooleanField comparisons, which is impossible otherwise (which is my case, btw, that your example below doesn't solve). The only reason not to teach Django understand True/False literals is to allow people set these variables in templates themselves, but I really don't think you'd like to encourage such practice.

The expression you want is simply:

{% if closed %}

If you want the negation:

{% if not closed %}

(This, by the way, is normally considered good style in Python as well. Adding the no-op comparison == True is pointless - and so neither the majority of Python developers nor template writers would intuitively write this).

That's not what I want. In my case closed is NullBooleanField used as a filter for issue list. None means that both open and closed issues should be returned. I need to distinguish between None and False.

comment:4 by Simon Charette, 13 years ago

I know it might feel a bit hackish but I think you get work around this limitation by using the default_if_none filter.

{% if closed|default_if_none:'None' == 'None' %}
  None
{% else %}{% if closed %}
  True
{% else %}
  False
{% endif %}{% endif %}

comment:5 by Luke Plant, 13 years ago

Description: modified (diff)
Needs documentation: unset
Summary: Invalid '==' expression silently ignored leading to invalid resultAllow 'True', 'False' and 'None' to resolve to corresponding Python objects
Triage Stage: UnreviewedDesign decision needed
Type: BugNew feature
UI/UX: unset

Your initial example only did a comparison to True, and didn't mention any comparison to None. I am not a mind reader!

The ticket has now changed in scope to the feature addition "Allow 'True', 'False' and 'None' to resolve to corresponding Python objects".

I can see why this would be useful, but I'm not entirely convinced, given that we've survived without these for a long time. Therefore marking DDN.

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