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 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 11 months, 3 weeks ago

Comments

Please login first before commenting.