| 744 | | is a list of ``Person`` objects that have ``first_name``, ``last_name``, and |
|---|
| 745 | | ``gender`` attributes, and you'd like to display a list that looks like: |
|---|
| | 744 | is a list of people represented by dictionaries with ``first_name``, |
|---|
| | 745 | ``last_name``, and ``gender`` keys:: |
|---|
| | 746 | |
|---|
| | 747 | people = [ |
|---|
| | 748 | {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'}, |
|---|
| | 749 | {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'}, |
|---|
| | 750 | {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'}, |
|---|
| | 751 | {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'}, |
|---|
| | 752 | {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'}, |
|---|
| | 753 | ] |
|---|
| | 754 | |
|---|
| | 755 | ...and you'd like to display a hierarchical list that is ordered by gender, |
|---|
| | 756 | like this: |
|---|
| 771 | | As you can see, ``{% regroup %}`` populates a variable with a list of objects |
|---|
| 772 | | with ``grouper`` and ``list`` attributes. ``grouper`` contains the item that |
|---|
| 773 | | was grouped by; ``list`` contains the list of objects that share that |
|---|
| 774 | | ``grouper``. In this case, ``grouper`` would be ``Male``, ``Female`` and |
|---|
| 775 | | ``Unknown``, and ``list`` is the list of people with those genders. |
|---|
| 776 | | |
|---|
| 777 | | Note that ``{% regroup %}`` does not work when the list to be grouped is not |
|---|
| 778 | | sorted by the key you are grouping by! This means that if your list of people |
|---|
| 779 | | was not sorted by gender, you'd need to make sure it is sorted before using it, |
|---|
| 780 | | i.e.:: |
|---|
| 781 | | |
|---|
| 782 | | {% regroup people|dictsort:"gender" by gender as grouped %} |
|---|
| | 784 | Let's walk through this example. ``{% regroup %}`` takes three arguments: the |
|---|
| | 785 | list you want to regroup, the attribute to group by, and the name of the |
|---|
| | 786 | resulting list. Here, we're regrouping the ``people`` list by the ``gender`` |
|---|
| | 787 | attribute and calling the result ``gender_list``. |
|---|
| | 788 | |
|---|
| | 789 | ``{% regroup %}`` produces a list (in this case, ``gender_list``) of |
|---|
| | 790 | **group objects**. Each group object has two attributes: |
|---|
| | 791 | |
|---|
| | 792 | * ``grouper`` -- the item that was grouped by (e.g., the string "Male" or |
|---|
| | 793 | "Female"). |
|---|
| | 794 | * ``list`` -- a list of all items in this group (e.g., a list of all people |
|---|
| | 795 | with gender='Male'). |
|---|
| | 796 | |
|---|
| | 797 | Note that ``{% regroup %}`` does not order its input! Our example relies on |
|---|
| | 798 | the fact that the ``people`` list was ordered by ``gender`` in the first place. |
|---|
| | 799 | If the ``people`` list did *not* order its members by ``gender``, the regrouping |
|---|
| | 800 | would naively display more than one group for a single gender. For example, |
|---|
| | 801 | say the ``people`` list was set to this (note that the males are not grouped |
|---|
| | 802 | together):: |
|---|
| | 803 | |
|---|
| | 804 | people = [ |
|---|
| | 805 | {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'}, |
|---|
| | 806 | {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'}, |
|---|
| | 807 | {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'}, |
|---|
| | 808 | {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'}, |
|---|
| | 809 | {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'}, |
|---|
| | 810 | ] |
|---|
| | 811 | |
|---|
| | 812 | With this input for ``people``, the example ``{% regroup %}`` template code |
|---|
| | 813 | above would result in the following output: |
|---|
| | 814 | |
|---|
| | 815 | * Male: |
|---|
| | 816 | * Bill Clinton |
|---|
| | 817 | * Unknown: |
|---|
| | 818 | * Pat Smith |
|---|
| | 819 | * Female: |
|---|
| | 820 | * Margaret Thatcher |
|---|
| | 821 | * Male: |
|---|
| | 822 | * George Bush |
|---|
| | 823 | * Female: |
|---|
| | 824 | * Condoleezza Rice |
|---|
| | 825 | |
|---|
| | 826 | The easiest solution to this gotcha is to make sure in your view code that the |
|---|
| | 827 | data is ordered according to how you want to display it. |
|---|
| | 828 | |
|---|
| | 829 | Another solution is to sort the data in the template using the ``dictsort`` |
|---|
| | 830 | filter, if your data is in a list of dictionaries:: |
|---|
| | 831 | |
|---|
| | 832 | {% regroup people|dictsort:"gender" by gender as gender_list %} |
|---|