Opened 17 years ago

Closed 16 years ago

Last modified 14 years ago

#5172 closed (wontfix)

Extend the {% for %} tag to work as a simple loop

Reported by: Chris Beaven Owned by: nobody
Component: Template system Version:
Severity: Keywords: for-tag enhancement feature
Cc: me@…, danielcristian@… 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

It's come up several times in IRC that people wanted to be able to just do a simple loop (repeat this X times) in their template.

The attached patch extends the {% for %} tag so it can also work like this:

{% for 5 %}
repeat me
{% endfor %}

It also works with integer variables and the forloop variable is still available within the loop:

{% for my_integer %}
loop: {{ forloop.counter }}
{% endfor %}

Attachments (2)

simple-for.patch (6.0 KB ) - added by Chris Beaven 17 years ago.
numerical-foo-loop.diff (5.6 KB ) - added by Vincent Foley 16 years ago.

Download all attachments as: .zip

Change History (16)

by Chris Beaven, 17 years ago

Attachment: simple-for.patch added

comment:1 by Chris Beaven, 17 years ago

Triage Stage: UnreviewedDesign decision needed

Tests and docs included, just need a decision.

comment:2 by Adrian Holovaty, 17 years ago

Hmm, this one merits some discussion. I like the general idea but need to mull over the syntax.

comment:3 by Philippe Raoult, 17 years ago

Keywords: feature added

by Vincent Foley, 16 years ago

Attachment: numerical-foo-loop.diff added

comment:4 by Vincent Foley, 16 years ago

Needs documentation: set

I added a patch of my own. It's more complex than SmileyChris' and needs documentation (and possibly more tests.) Let me know what you think of the general syntax. The patch is attached.

Example usage:

{% for i 1 to 5 %}
    {{ i }}
{% endfor %}

{% for i 1 to 5 by 2 exclusive %}
    {{ i }}
{% endfor %}

{% for i 5 to 1 by -2 %}
    {{ i }}
{% endfor %}

comment:5 by anonymous, 16 years ago

Ugh, I don't like at all, sorry gnuvince. The aim isn't to make Django templates into python...

comment:6 by durdinator, 16 years ago

Cc: me@… added

Why a significant syntax change instead of a one-liner filter?

@register.filter
def times(count):
    return range(int(count))
{% for item in 5|times %}
  repeat me
{% endfor %}

in reply to:  6 comment:7 by Chris Beaven, 16 years ago

Replying to durdinator:

Why a significant syntax change instead of a one-liner filter?

Because it looks simpler (and it's a syntax extension, really) and because then you're stuck with a pointless item context var.

Neither of which are convincing arguments. And talking about this at sprint, it seemed like the core would just prefer to have a new filter named something separate anyway so I don't hold much hope for my patch really :)

comment:8 by Vincent Foley, 16 years ago

How about something like:

{% times 5 %}
    {{ times.iter0 }}
    {{ times.iter1 }}
    <br />
{% endtimes %}

# Output
0 1
1 2
2 3
3 4
4 5

comment:9 by Vincent Foley, 16 years ago

P.S.: times is just a tentative name. I think repeat would be better.

comment:10 by Chris Beaven, 16 years ago

And that's why I like it attached to {% for %} - then you get all of the forloop context variable goodness for free.

comment:11 by Jacob, 16 years ago

Resolution: wontfix
Status: newclosed

I just can't come up with a use case that isn't something better done in a view or better done by just writing out the rows by hand. Besides, this is a pretty simple thing to add as a custom tag in your app.

comment:12 by danielcristian, 16 years ago

Cc: danielcristian@… added
Resolution: wontfix
Status: closedreopened

I had this model:

class Mana(models.Model):
    name = models.CharField(u'Mana', max_length=200, unique=True)
    image = models.ImageField(u'Symbol', upload_to='manas/')

class Cost(models.Model):
    card = models.ForeignKey(Card)
    quantity = models.IntegerField('Quantity', max_length=2)
    mana = models.ForeignKey(Mana, related_name=u'mana', verbose_name=u'Mana')

(Yes, it's related to Magic Cards...)

Some cards had a cost with a quantity value (1 Forest, 3 Islands, 5 Mountains), and I need to loop quantity times to show n-times the image cost.

It could be done with this kind of loop.

comment:13 by James Bennett, 16 years ago

Resolution: wontfix
Status: reopenedclosed

Please do not reopen a ticket that's been marked "wontfix" by a core developer; if you strongly disagree, consider starting a discussion on the developers' mailing list.

in reply to:  11 comment:14 by anonymous, 14 years ago

Has patch: unset
Needs documentation: unset
Version: SVN

Replying to jacob:

I just can't come up with a use case that isn't something better done in a view or better done by just writing out the rows by hand. Besides, this is a pretty simple thing to add as a custom tag in your app.

This ticked is old, but to present you with a scenario that I'm into right now: I need to create a varying number of radiobuttons, depending of the number of choices allowed by the parents settings. The parent has a "number of objects allowed" field in the model. I therefore need to repeat a tag that can do the same thing {% for %}, but not iterating over an array or set, but just a variable number.

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