Opened 10 years ago
Closed 10 years ago
#22767 closed Bug (duplicate)
Unexpected value for an unset variable with length filter in templates
Reported by: | György Kiss | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | 1.6 |
Severity: | Normal | Keywords: | |
Cc: | gregchapple1@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Not sure if this is a bug or I'm just missing something, but I expected this to be False
anyway:
{% if groups|length > 0 %}
This will be True
in Django 1.6.5 if groups
is an unset variable. The TEMPLATE_STRING_IF_INVALID
setting has the default value (empty string).
I know it's not idiomatic code and I fixed it:
{% if groups %}
(which works as expected), but other newbies like me can have a hard time figuring out what's wrong.
I checked {% if None|length > 0 %}
and it is also True
, which is clearly not expected.
Change History (4)
comment:2 by , 10 years ago
Saying that, I would still expect the length
filter to return 0
unless the length is indeed something other than that. From taking a quick look, it seems to return an empty string if the value given does not support len()
. I changed this to instead return 0
and it does indeed fix the issue, though it makes a ton of tests fail. Perhaps someone with a little more experience with filters can provide some insight as to why it currently returns a string?
comment:3 by , 10 years ago
Cc: | added |
---|
I agree that this is somewhat unexpected, though I don't know if it's a bug. If you were to do the same in Python, and tried to get the length of something which is None, you would get a TypeError. To get around that you would either use a try/except block, or first check if the variable is not None. I think it's reasonable to do the same in your templates. ie:
Edit:
Also, in your example above, I don't think
{% if None|length > 0 %}
is doing what you think. In this case, django will treatNone
as just another template variable. So in fact it is treated the same asgroups
in your first example. You can confirm this like so:If you run this in a browser you will see
'test'
returned in the response.