|
@@ -771,48 +771,41 @@ regroup
|
|
|
|
|
|
Regroups a list of alike objects by a common attribute.
|
|
|
|
|
|
-This complex tag is best illustrated by use of an example: say that ``people``
|
|
|
-is a list of people represented by dictionaries with ``first_name``,
|
|
|
-``last_name``, and ``gender`` keys:
|
|
|
+This complex tag is best illustrated by way of an example: say that "places" is a list of cities represented by dictionaries containing ``"name"``, ``"population"``, and ``"country"`` keys:
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
- people = [
|
|
|
- {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
|
|
|
- {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
|
|
|
- {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
|
|
|
- {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
|
|
|
- {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
|
|
|
+ cities = [
|
|
|
+ {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
|
|
|
+ {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
|
|
|
+ {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
|
|
|
+ {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
|
|
|
+ {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
|
|
|
]
|
|
|
|
|
|
-...and you'd like to display a hierarchical list that is ordered by gender,
|
|
|
-like this:
|
|
|
+...and you'd like to display a hierarchical list that is ordered by country, like this:
|
|
|
|
|
|
-* Male:
|
|
|
+* India
|
|
|
+ * Mumbai: 19,000,000
|
|
|
+ * Calcutta: 15,000,000
|
|
|
+* USA
|
|
|
+ * New York: 20,000,000
|
|
|
+ * Chicago: 7,000,000
|
|
|
+* Japan
|
|
|
+ * Tokyo: 33,000,000
|
|
|
|
|
|
- * George Bush
|
|
|
- * Bill Clinton
|
|
|
|
|
|
-* Female:
|
|
|
-
|
|
|
- * Margaret Thatcher
|
|
|
- * Condoleezza Rice
|
|
|
-
|
|
|
-* Unknown:
|
|
|
-
|
|
|
- * Pat Smith
|
|
|
-
|
|
|
-You can use the ``{% regroup %}`` tag to group the list of people by gender.
|
|
|
+You can use the ``{% regroup %}`` tag to group the list of cities by country.
|
|
|
The following snippet of template code would accomplish this::
|
|
|
|
|
|
- {% regroup people by gender as gender_list %}
|
|
|
+ {% regroup cities by country as country_list %}
|
|
|
|
|
|
<ul>
|
|
|
- {% for gender in gender_list %}
|
|
|
- <li>{{ gender.grouper }}
|
|
|
+ {% for country in country_list %}
|
|
|
+ <li>{{ country.grouper }}
|
|
|
<ul>
|
|
|
- {% for item in gender.list %}
|
|
|
- <li>{{ item.first_name }} {{ item.last_name }}</li>
|
|
|
+ {% for item in country.list %}
|
|
|
+ <li>{{ item.name }}: {{ item.population }}</li>
|
|
|
{% endfor %}
|
|
|
</ul>
|
|
|
</li>
|
|
@@ -821,56 +814,45 @@ The following snippet of template code would accomplish this::
|
|
|
|
|
|
Let's walk through this example. ``{% regroup %}`` takes three arguments: the
|
|
|
list you want to regroup, the attribute to group by, and the name of the
|
|
|
-resulting list. Here, we're regrouping the ``people`` list by the ``gender``
|
|
|
-attribute and calling the result ``gender_list``.
|
|
|
+resulting list. Here, we're regrouping the ``cities`` list by the ``country``
|
|
|
+attribute and calling the result ``country_list``.
|
|
|
|
|
|
-``{% regroup %}`` produces a list (in this case, ``gender_list``) of
|
|
|
+``{% regroup %}`` produces a list (in this case, ``country_list``) of
|
|
|
**group objects**. Each group object has two attributes:
|
|
|
|
|
|
-* ``grouper`` -- the item that was grouped by (e.g., the string "Male" or
|
|
|
- "Female").
|
|
|
-* ``list`` -- a list of all items in this group (e.g., a list of all people
|
|
|
- with gender='Male').
|
|
|
+* ``grouper`` -- the item that was grouped by (e.g., the string "India" or
|
|
|
+ "Japan").
|
|
|
+* ``list`` -- a list of all items in this group (e.g., a list of all cities
|
|
|
+ with country='India').
|
|
|
|
|
|
Note that ``{% regroup %}`` does not order its input! Our example relies on
|
|
|
-the fact that the ``people`` list was ordered by ``gender`` in the first place.
|
|
|
-If the ``people`` list did *not* order its members by ``gender``, the
|
|
|
-regrouping would naively display more than one group for a single gender. For
|
|
|
-example, say the ``people`` list was set to this (note that the males are not
|
|
|
+the fact that the ``cities`` list was ordered by ``country`` in the first place.
|
|
|
+If the ``cities`` list did *not* order its members by ``country``, the
|
|
|
+regrouping would naively display more than one group for a single country. For
|
|
|
+example, say the ``cities`` list was set to this (note that the countries are not
|
|
|
grouped together):
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
- people = [
|
|
|
- {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
|
|
|
- {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
|
|
|
- {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
|
|
|
- {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
|
|
|
- {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
|
|
|
+ cities = [
|
|
|
+ {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
|
|
|
+ {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
|
|
|
+ {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
|
|
|
+ {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
|
|
|
+ {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
|
|
|
]
|
|
|
|
|
|
-With this input for ``people``, the example ``{% regroup %}`` template code
|
|
|
+With this input for ``cities``, the example ``{% regroup %}`` template code
|
|
|
above would result in the following output:
|
|
|
|
|
|
-* Male:
|
|
|
-
|
|
|
- * Bill Clinton
|
|
|
-
|
|
|
-* Unknown:
|
|
|
-
|
|
|
- * Pat Smith
|
|
|
-
|
|
|
-* Female:
|
|
|
-
|
|
|
- * Margaret Thatcher
|
|
|
-
|
|
|
-* Male:
|
|
|
-
|
|
|
- * George Bush
|
|
|
-
|
|
|
-* Female:
|
|
|
-
|
|
|
- * Condoleezza Rice
|
|
|
+* India
|
|
|
+ * Mumbai: 19,000,000
|
|
|
+* USA
|
|
|
+ * New York: 20,000,000
|
|
|
+* India
|
|
|
+ * Calcutta: 15,000,000
|
|
|
+* Japan
|
|
|
+ * Tokyo: 33,000,000
|
|
|
|
|
|
The easiest solution to this gotcha is to make sure in your view code that the
|
|
|
data is ordered according to how you want to display it.
|
|
@@ -878,27 +860,26 @@ data is ordered according to how you want to display it.
|
|
|
Another solution is to sort the data in the template using the
|
|
|
:tfilter:`dictsort` filter, if your data is in a list of dictionaries::
|
|
|
|
|
|
- {% regroup people|dictsort:"gender" by gender as gender_list %}
|
|
|
-
|
|
|
+ {% regroup cities|dictsort:"country" by country as country_list %}
|
|
|
|
|
|
Grouping on other properties
|
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
Any valid template lookup is a legal grouping attribute for the regroup
|
|
|
tag, including methods, attributes, dictionary keys and list items. For
|
|
|
-example, if the "gender" field is a foreign key to a class with
|
|
|
+example, if the "country" field is a foreign key to a class with
|
|
|
an attribute "description," you could use::
|
|
|
|
|
|
- {% regroup people by gender.description as gender_list %}
|
|
|
+ {% regroup cities by country.description as country_list %}
|
|
|
|
|
|
-Or, if ``gender`` is a field with ``choices``, it will have a
|
|
|
+Or, if ``country`` is a field with ``choices``, it will have a
|
|
|
:meth:`^django.db.models.Model.get_FOO_display` method available as an
|
|
|
attribute, allowing you to group on the display string rather than the
|
|
|
``choices`` key::
|
|
|
|
|
|
- {% regroup people by get_gender_display as gender_list %}
|
|
|
+ {% regroup cities by get_country_display as country_list %}
|
|
|
|
|
|
-``{{ gender.grouper }}`` will now display the value fields from the
|
|
|
+``{{ country.grouper }}`` will now display the value fields from the
|
|
|
``choices`` set rather than the keys.
|
|
|
|
|
|
.. templatetag:: spaceless
|