Ticket #2146: regroup.diff

File regroup.diff, 3.0 KB (added by Matias Hermanrud Fjeld <mhf@…>, 9 years ago)
  • django/template/defaulttags.py

     
    195195        and_ = 0,
    196196        or_ = 1
    197197
     198class Group(list):
     199    def __init__(self, grouper, groups):
     200        self.grouper = grouper
     201        super(Group, self).__init__(groups)
     202
     203    def __str__(self):
     204        return str(self.grouper)
     205
     206    # for backwards compatability
     207    def __getitem__(self, key):
     208        if key == 'list':
     209            return self
     210        elif key == 'grouper':
     211            return self.grouper
     212        else:
     213            raise KeyError
     214
    198215class RegroupNode(Node):
    199216    def __init__(self, target, expression, var_name):
    200217        self.target, self.expression = target, expression
     
    205222        if obj_list == '': # target_var wasn't found in context; fail silently
    206223            context[self.var_name] = []
    207224            return ''
    208         output = [] # list of dictionaries in the format {'grouper': 'key', 'list': [list of contents]}
     225        output = [] # list of Group objects
    209226        for obj in obj_list:
    210227            grouper = self.expression.resolve(Context({'var': obj}))
    211228            # TODO: Is this a sensible way to determine equality?
    212             if output and repr(output[-1]['grouper']) == repr(grouper):
    213                 output[-1]['list'].append(obj)
     229            if output and repr(output[-1].grouper) == repr(grouper):
     230                output[-1].append(obj)
    214231            else:
    215                 output.append({'grouper': grouper, 'list': [obj]})
     232                output.append(Group(grouper, [obj]))
    216233        context[self.var_name] = output
    217234        return ''
    218235
     
    722739        {% regroup people by gender as grouped %}
    723740        <ul>
    724741        {% for group in grouped %}
    725             <li>{{ group.grouper }}
     742            <li>{{ group }}
    726743            <ul>
    727                 {% for item in group.list %}
     744                {% for item in group %}
    728745                <li>{{ item }}</li>
    729746                {% endfor %}
    730747            </ul>
     
    732749        </ul>
    733750
    734751    As you can see, ``{% regroup %}`` populates a variable with a list of
    735     objects with ``grouper`` and ``list`` attributes.  ``grouper`` contains the
    736     item that was grouped by; ``list`` contains the list of objects that share
    737     that ``grouper``.  In this case, ``grouper`` would be ``Male``, ``Female``
    738     and ``Unknown``, and ``list`` is the list of people with those genders.
     752    group objects. The group objects are lists of objects that share the
     753    same ``grouper``. group objects behave just like lists, with one
     754    exception: the str()-method returns the grouper. In this case, the
     755    ```groupers``` would be would be ``Male``, ``Female``
     756    and ``Unknown``, and each group is the list of people with those genders.
    739757
    740758    Note that `{% regroup %}`` does not work when the list to be grouped is not
    741759    sorted by the key you are grouping by!  This means that if your list of
Back to Top