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: | 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 )
[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)
follow-up: 3 comment:1 by , 13 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 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.
comment:3 by , 13 years ago
Needs documentation: | set |
---|---|
Resolution: | invalid |
Status: | closed → reopened |
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 , 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 , 13 years ago
Description: | modified (diff) |
---|---|
Needs documentation: | unset |
Summary: | Invalid '==' expression silently ignored leading to invalid result → Allow 'True', 'False' and 'None' to resolve to corresponding Python objects |
Triage Stage: | Unreviewed → Design decision needed |
Type: | Bug → New 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.
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 you want the negation:
(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).