#3481 closed (wontfix)
request: else part for a for loop or make if to create variable
Reported by: | 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)
Change History (9)
comment:1 by , 18 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
comment:2 by , 18 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 , 18 years ago
In the meanwhile, maybe good alternative names would be 'nofor' or just 'none'.
comment:4 by , 18 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 , 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:7 by , 17 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Since there is a workaround and that no one gave an idea...
comment:8 by , 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?
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?