Login

range tag

Author:
marco.fucci
Posted:
May 22, 2009
Language:
Python
Version:
1.0
Score:
2 (after 2 ratings)

Create a list containing an arithmetic progression that can be iterated through in templates. Emulate the range syntax. You can use either numbers or variables.

Syntax:
{% num_range [start] stop [step] as some_range %}

{% for i in some_range %}
  ... do something
{% endfor %}

About the author: Take a look at my website

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class RangeNode(template.Node):
    def __init__(self, start, stop, step, context_name):
        if not self._isint(start):
            self.start = template.Variable(start)
        else:
            self.start = start

        if not self._isint(stop):
            self.stop = template.Variable(stop)
        else:
            self.stop = stop

        if not self._isint(step):
            self.step = template.Variable(step)
        else:
            self.step = step

        self.context_name = context_name

    def _isint(self, value):
        return isinstance(value, int)

    def _resolveint(self, value, context):
        if self._isint(value):
            return value
        return int(value.resolve(context))

    def render(self, context):
        start = self._resolveint(self.start, context)
        stop = self._resolveint(self.stop, context)
        step = self._resolveint(self.step, context)
    
        context[self.context_name] = range(start, stop, step)
        return ""

@register.tag
def num_range(parser, token):
    """
    Create a list containing an arithmetic progression that can be 
    iterated through in templates.

    If the start argument is omitted, it defaults to 0. 
    If step is positive, the last element is the largest start + i * step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. 
    step must not be zero (or else ValueError is raised).
    
    see http://docs.python.org/library/functions.html#range for more details.

    Syntax:
    {% num_range [start] stop [step] as some_range %}
    
    {% for i in some_range %}
      ... do something
    {% endfor %}
    """
    bits = token.contents.split()
    len_bits = len(bits)

    if len_bits not in range(4, 7):
        raise template.TemplateSyntaxError(_('%s tag requires between three and fifth arguments') % bits[0])
    if bits[-2] != 'as':
        raise template.TemplateSyntaxError(_("last but one argument to %s tag must be 'as'") % bits[0])

    #DEFAULTS
    start, step = 0, 1

    as_index = bits.index('as')

    if as_index == 2:
        stop = bits[1]
    else:
        start, stop = bits[1], bits[2]
        
        if as_index == 4:
            step = bits[3]

    context_name = bits[-1]

    return RangeNode(start, stop, step, context_name)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.