Code

Ticket #2146: regroup.diff

File regroup.diff, 3.0 KB (added by Matias Hermanrud Fjeld <mhf@…>, 8 years ago)
Line 
1Index: django/template/defaulttags.py
2===================================================================
3--- django/template/defaulttags.py      (revision 3122)
4+++ django/template/defaulttags.py      (working copy)
5@@ -195,6 +195,23 @@
6         and_ = 0,
7         or_ = 1
8 
9+class Group(list):
10+    def __init__(self, grouper, groups):
11+        self.grouper = grouper
12+        super(Group, self).__init__(groups)
13+
14+    def __str__(self):
15+        return str(self.grouper)
16+
17+    # for backwards compatability
18+    def __getitem__(self, key):
19+        if key == 'list':
20+            return self
21+        elif key == 'grouper':
22+            return self.grouper
23+        else:
24+            raise KeyError
25+
26 class RegroupNode(Node):
27     def __init__(self, target, expression, var_name):
28         self.target, self.expression = target, expression
29@@ -205,14 +222,14 @@
30         if obj_list == '': # target_var wasn't found in context; fail silently
31             context[self.var_name] = []
32             return ''
33-        output = [] # list of dictionaries in the format {'grouper': 'key', 'list': [list of contents]}
34+        output = [] # list of Group objects
35         for obj in obj_list:
36             grouper = self.expression.resolve(Context({'var': obj}))
37             # TODO: Is this a sensible way to determine equality?
38-            if output and repr(output[-1]['grouper']) == repr(grouper):
39-                output[-1]['list'].append(obj)
40+            if output and repr(output[-1].grouper) == repr(grouper):
41+                output[-1].append(obj)
42             else:
43-                output.append({'grouper': grouper, 'list': [obj]})
44+                output.append(Group(grouper, [obj]))
45         context[self.var_name] = output
46         return ''
47 
48@@ -722,9 +739,9 @@
49         {% regroup people by gender as grouped %}
50         <ul>
51         {% for group in grouped %}
52-            <li>{{ group.grouper }}
53+            <li>{{ group }}
54             <ul>
55-                {% for item in group.list %}
56+                {% for item in group %}
57                 <li>{{ item }}</li>
58                 {% endfor %}
59             </ul>
60@@ -732,10 +749,11 @@
61         </ul>
62 
63     As you can see, ``{% regroup %}`` populates a variable with a list of
64-    objects with ``grouper`` and ``list`` attributes.  ``grouper`` contains the
65-    item that was grouped by; ``list`` contains the list of objects that share
66-    that ``grouper``.  In this case, ``grouper`` would be ``Male``, ``Female``
67-    and ``Unknown``, and ``list`` is the list of people with those genders.
68+    group objects. The group objects are lists of objects that share the
69+    same ``grouper``. group objects behave just like lists, with one
70+    exception: the str()-method returns the grouper. In this case, the
71+    ```groupers``` would be would be ``Male``, ``Female``
72+    and ``Unknown``, and each group is the list of people with those genders.
73 
74     Note that `{% regroup %}`` does not work when the list to be grouped is not
75     sorted by the key you are grouping by!  This means that if your list of