Ticket #5172: simple-for.patch
File simple-for.patch, 6.0 KB (added by , 17 years ago) |
---|
-
django/template/defaulttags.py
79 79 reversed = ' reversed' 80 80 else: 81 81 reversed = '' 82 return "<For Node: for %s in %s, tail_len: %d%s>" % \ 83 (', '.join( self.loopvars ), self.sequence, len(self.nodelist_loop), reversed) 82 loopvars = loopvars and '%s in ' % ', '.join(self.loopvars) or '' 83 return "<For Node: for %s%s, length of: %d%s>" % (loopvars, 84 self.sequence, len(self.nodelist_loop), reversed) 84 85 85 86 def __iter__(self): 86 87 for node in self.nodelist_loop: … … 106 107 values = [] 107 108 if values is None: 108 109 values = [] 110 if not self.loopvars: 111 # It's a simple integer-based loop 112 try: 113 values = range(int(values)) 114 except (ValueError, TypeError): 115 values = [] 109 116 if not hasattr(values, '__len__'): 110 117 values = list(values) 111 118 len_values = len(values) … … 128 135 if unpack: 129 136 # If there are multiple loop variables, unpack the item into them. 130 137 context.update(dict(zip(self.loopvars, item))) 131 el se:138 elif self.loopvars: 132 139 context[self.loopvars[0]] = item 133 140 for node in self.nodelist_loop: 134 141 nodelist.append(node.render(context)) … … 567 574 current one 568 575 ========================== ================================================ 569 576 577 You can also set up a simple integer loop by passing in just an integer. 578 Nothing will be added to the context except for the ``forloop`` variable. 579 580 {% for 5 %} 581 loop: {{ forloop.counter }} 582 {% endfor %} 583 {% for my_integer %} 584 loop: {{ forloop.counter }} 585 {% endfor %} 570 586 """ 571 587 bits = token.contents.split() 572 if len(bits) < 4: 573 raise TemplateSyntaxError, "'for' statements should have at least four words: %s" % token.contents 588 if len(bits) < 4 and len(bits) != 2: 589 raise TemplateSyntaxError, ("Invalid format for 'for' tag: %s" % 590 token.contents) 574 591 575 reversed = bits[-1] == 'reversed' 576 in_index = reversed and -3 or -2 577 if bits[in_index] != 'in': 578 raise TemplateSyntaxError, "'for' statements should use the format 'for x in y': %s" % token.contents 579 580 loopvars = re.sub(r' *, *', ',', ' '.join(bits[1:in_index])).split(',') 581 for var in loopvars: 582 if not var or ' ' in var: 583 raise TemplateSyntaxError, "'for' tag received an invalid argument: %s" % token.contents 584 585 sequence = parser.compile_filter(bits[in_index+1]) 592 if len(bits) == 2: 593 reversed = False 594 loopvars = [] 595 sequence = parser.compile_filter(bits[1]) 596 else: 597 reversed = bits[-1] == 'reversed' 598 in_index = reversed and -3 or -2 599 if bits[in_index] != 'in': 600 raise TemplateSyntaxError, "'for' statements should use the format 'for x in y': %s" % token.contents 601 602 loopvars = re.sub(r' *, *', ',', ' '.join(bits[1:in_index])).split(',') 603 for var in loopvars: 604 if not var or ' ' in var: 605 raise TemplateSyntaxError, "'for' tag received an invalid argument: %s" % token.contents 606 607 sequence = parser.compile_filter(bits[in_index+1]) 586 608 nodelist_loop = parser.parse(('endfor',)) 587 609 parser.delete_first_token() 588 610 return ForNode(loopvars, sequence, reversed, nodelist_loop) -
docs/templates.txt
492 492 current one 493 493 ========================== ================================================ 494 494 495 **New in Django development version** 496 You can also set up a simple loop by passing just an integer variable (or 497 constant):: 498 499 {% for var %} 500 loop: {{ forloop.counter }} 501 {% endfor %} 502 495 503 if 496 504 ~~ 497 505 -
tests/regressiontests/templates/tests.py
356 356 'for-tag-unpack11': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, ("one:1,/two:2,/", "one:1,INVALID/two:2,INVALID/")), 357 357 'for-tag-unpack12': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2))}, ("one:1,carrot/two:2,/", "one:1,carrot/two:2,INVALID/")), 358 358 'for-tag-unpack13': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2, 'cheese'))}, ("one:1,carrot/two:2,cheese/", "one:1,carrot/two:2,cheese/")), 359 'for-tag-simple01': ("{% for 5 %}{{ forloop.counter }},{% endfor %}", {}, "1,2,3,4,5,"), 360 'for-tag-simple02': ('{% for "5" %}{{ forloop.counter }},{% endfor %}', {}, "1,2,3,4,5,"), 361 'for-tag-simple03': ('{% for "not-a-number" %}{{ forloop.counter }},{% endfor %}', {}, ""), 362 'for-tag-simple04': ('{% for number %}{{ forloop.counter }},{% endfor %}', {'number': 5}, "1,2,3,4,5,"), 363 'for-tag-simple05': ('{% for number %}{{ forloop.counter }},{% endfor %}', {'number': '5'}, "1,2,3,4,5,"), 364 'for-tag-simple06': ('{% for number %}{{ forloop.counter }},{% endfor %}', {'number': 'not-a-number'}, ""), 365 'for-tag-simple07': ('{% for number %}{{ forloop.counter }},{% endfor %}', {}, ""), 359 366 360 367 ### IF TAG ################################################################ 361 368 'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"),