Opened 7 years ago

Closed 7 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


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:1 Changed 7 years ago by Greg Chapple

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:

{% if groups %}
    {% if groups|length > 0 %}
    {% else %}
       no groups :(
    {% endif %}
{% else %}
    groups not defined
{% end %}


Also, in your example above, I don't think {% if None|length > 0 %} is doing what you think. In this case, django will treat None as just another template variable. So in fact it is treated the same as groups in your first example. You can confirm this like so:

from django.shortcuts import render_to_response
def test_view(request):
    return render_to_response("test.html", {'None': 'test'})

##### test.html

{{ None }}

If you run this in a browser you will see 'test' returned in the response.

Last edited 7 years ago by Greg Chapple (previous) (diff)

comment:2 Changed 7 years ago by Greg Chapple

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 Changed 7 years ago by Greg Chapple

Cc: gregchapple1@… added

comment:4 Changed 7 years ago by Tim Graham

Resolution: duplicate
Status: newclosed

Duplicate of #18400.

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