Opened 17 years ago

Closed 17 years ago

Last modified 17 years ago

#3481 closed (wontfix)

request: else part for a for loop or make if to create variable

Reported by: jimmy@… Owned by: Adrian Holovaty
Component: Template system Version:
Severity: Keywords: for if else loop
Cc: Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using the object_detail generic view:

If you have for examle a blog entry Entry(), and comments Comment() on it;
I would use this to loop for comments:

{% for comment in object.comment_set.all %}
   {{ comment.body_text }}
   <hr>
{% endfor%}

Now the problem is; it is impossible to display something in case there are no comments without hitting the database again.

It could be fixed with an '{% elsefor %}' or by making it possible to assign object.comment_set.all to some var once.

Another solution would be to make '{% if object.comment_set_all %}' create a variable 'if.result' or something.

Attachments (1)

for_else.diff (4.2 KB ) - added by rodolfo.3@… 17 years ago.
This patch allow a tag "else" in a "for" loop.

Download all attachments as: .zip

Change History (9)

comment:1 by Chris Beaven, 17 years ago

Triage Stage: UnreviewedDesign decision needed

It would be good to have {% else %} for {% for %} tags - I know we want to stay away from too much logic, but this is a very common use case and it's not that difficult to understand is it?

comment:2 by Malcolm Tredinnick, 17 years ago

It sounds like you are wanting "else" to only be executed when the "for" is not looped through. However, this is not the way it works in, for example, Python ("else" is executed when you don't break out of the loop prematurely). I don't think we want to implement it in a way that is so vastly different from Python: whilst we aren't implementing Python in templates, behaving completely the opposite way is going to be too confusing.

Setting a variable is a slippery slope and not really in the spirit of templates. Fixing #2430 will help a little bit here (the if-test will be faster and memory efficient). Knowing that you are going to be accessing result_set.all() multiple times and passing it in as a QuerySet to the template will help, too (that is the normal and recommended way to do this efficiently at the moment).

There may be another solution available, so I'll leave this open in case another developer has an idea, but I am very much against using "else" in the proposed way; it's just too confusing for Python programmers.

comment:3 by jimmy@…, 17 years ago

In the meanwhile, maybe good alternative names would be 'nofor' or just 'none'.

comment:4 by Chris Beaven, 17 years ago

Version: 0.95

Yea, silly choice of words there by me. An alternate name like nofor would be a much better choice.

Really, I'm only a +0 on this ticket anyway and was just chiming in while reviewing.

comment:5 by nick.lane.au@…, 17 years ago

Can use the new "with" tag for this.

{% with object.comment_set.all as comment_list %}
{% for comment in comment_list %}
   {{ comment.body_text }}
   <hr>
{% endfor%}
{% endwith %}

comment:6 by jimmy@…, 17 years ago

Great! This is a perfect solution!

comment:7 by Baptiste <baptiste.goupil@…>, 17 years ago

Resolution: wontfix
Status: newclosed

Since there is a workaround and that no one gave an idea...

by rodolfo.3@…, 17 years ago

Attachment: for_else.diff added

This patch allow a tag "else" in a "for" loop.

comment:8 by anonymous, 17 years ago

I'm add a patch to allow a tag "else" in a "for" loop. When the list is empty, it is called (as well "else" on a "if"):

{% for i in items %}
  {{ i }}
{% else %}
  no items
{% endfor %}

This is useful?

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