Ticket #6398: ticket6398-r9032.diff

File ticket6398-r9032.diff, 5.4 KB (added by jezdez, 7 years ago)

Updated patch to Django r9032 (http://github.com/jezdez/django/tree/ticket6398)

  • django/template/defaulttags.py

    diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
    index 8182cd4..22777b7 100644
    a b class FirstOfNode(Node): 
    8383        return u''
    8484
    8585class ForNode(Node):
    86     def __init__(self, loopvars, sequence, is_reversed, nodelist_loop):
     86    def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_default=None):
    8787        self.loopvars, self.sequence = loopvars, sequence
    8888        self.is_reversed = is_reversed
    8989        self.nodelist_loop = nodelist_loop
     90        if nodelist_default is None:
     91            self.nodelist_default = NodeList()
     92        else:
     93            self.nodelist_default = nodelist_default
    9094
    9195    def __repr__(self):
    9296        reversed_text = self.is_reversed and ' reversed' or ''
    class ForNode(Node): 
    97101    def __iter__(self):
    98102        for node in self.nodelist_loop:
    99103            yield node
     104        for node in self.nodelist_default:
     105            yield node
    100106
    101107    def get_nodes_by_type(self, nodetype):
    102108        nodes = []
    103109        if isinstance(self, nodetype):
    104110            nodes.append(self)
    105111        nodes.extend(self.nodelist_loop.get_nodes_by_type(nodetype))
     112        nodes.extend(self.nodelist_default.get_nodes_by_type(nodetype))
    106113        return nodes
    107114
    108115    def render(self, context):
    109         nodelist = NodeList()
    110116        if 'forloop' in context:
    111117            parentloop = context['forloop']
    112118        else:
    class ForNode(Node): 
    121127        if not hasattr(values, '__len__'):
    122128            values = list(values)
    123129        len_values = len(values)
     130        if len_values < 1:
     131            return self.nodelist_default.render(context)
     132        nodelist = NodeList()
    124133        if self.is_reversed:
    125134            values = reversed(values)
    126135        unpack = len(self.loopvars) > 1
    def do_for(parser, token): 
    610619            {{ key }}: {{ value }}
    611620        {% endfor %}
    612621
     622    The ``for`` tag can take an optional ``{% default %}`` clause that will
     623    be displayed if the given array is empty or could not be found::
     624
     625        <ul>
     626        {% for athlete in athlete_list %}
     627            <li>{{ athlete.name }}</li>
     628        {% default %}
     629            <li>Sorry, no athlete in this list!</li>
     630        {% endfor %}
     631        <ul>
     632
    613633    The for loop sets a number of variables available within the loop:
    614634
    615635        ==========================  ================================================
    def do_for(parser, token): 
    646666                                      " %s" % token.contents)
    647667
    648668    sequence = parser.compile_filter(bits[in_index+1])
    649     nodelist_loop = parser.parse(('endfor',))
    650     parser.delete_first_token()
    651     return ForNode(loopvars, sequence, is_reversed, nodelist_loop)
     669    nodelist_loop = parser.parse(('default', 'endfor',))
     670    token = parser.next_token()
     671    if token.contents == 'default':
     672        nodelist_default = parser.parse(('endfor',))
     673        parser.delete_first_token()
     674    else:
     675        nodelist_default = None
     676    return ForNode(loopvars, sequence, is_reversed, nodelist_loop, nodelist_default)
    652677do_for = register.tag("for", do_for)
    653678
    654679def do_ifequal(parser, token, negate):
  • docs/ref/templates/builtins.txt

    diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
    index a28cf4f..f2c6953 100644
    a b would display the keys and values of the dictionary:: 
    192192        {{ key }}: {{ value }}
    193193    {% endfor %}
    194194
     195.. versionadded:: 1.1
     196
     197The ``for`` tag can take an optional ``{% default %}`` clause that will be
     198displayed if the given array is empty or could not be found::
     199
     200    <ul>
     201    {% for athlete in athlete_list %}
     202        <li>{{ athlete.name }}</li>
     203    {% default %}
     204        <li>Sorry, no athlete in this list!</li>
     205    {% endfor %}
     206    <ul>
     207
    195208The for loop sets a number of variables available within the loop:
    196209
    197210    ==========================  ================================================
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index c69e7cd..6d728e9 100644
    a b class Templates(unittest.TestCase): 
    473473            '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/")),
    474474            '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/")),
    475475            '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/")),
     476            'for-tag-default01': ("{% for val in values %}{{ val }}{% default %}default text{% endfor %}", {"values": [1, 2, 3]}, "123"),
     477            'for-tag-default02': ("{% for val in values %}{{ val }}{% default %}values array empty{% endfor %}", {"values": []}, "values array empty"),
     478            'for-tag-default03': ("{% for val in values %}{{ val }}{% default %}values array not found{% endfor %}", {}, "values array not found"),
    476479
    477480            ### IF TAG ################################################################
    478481            'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"),
Back to Top