Django

Code

Changeset 5710

Show
Ignore:
Timestamp:
07/15/07 16:16:32 (1 year ago)
Author:
adrian
Message:

Improved docs/templates.txt section on the 'regroup' tag

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/docs/templates.txt

    r5674 r5710  
    742742 
    743743This complex tag is best illustrated by use of an example:  say that ``people`` 
    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: 
     744is 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, 
     756like this: 
    746757 
    747758    * Male: 
     
    754765        * Pat Smith 
    755766 
    756 The following snippet of template code would accomplish this dubious task:: 
    757  
    758     {% regroup people by gender as grouped %} 
     767You can use the ``{% regroup %}`` tag to group the list of people by gender. 
     768The following snippet of template code would accomplish this:: 
     769 
     770    {% regroup people by gender as gender_list %} 
     771 
    759772    <ul> 
    760     {% for group in grouped %} 
    761         <li>{{ group.grouper }} 
     773    {% for gender in gender_list %} 
     774        <li>{{ gender.grouper }} 
    762775        <ul> 
    763             {% for item in group.list %} 
    764             <li>{{ item }}</li> 
     776            {% for item in gender.list %} 
     777            <li>{{ item.first_name }} {{ item.last_name }}</li> 
    765778            {% endfor %} 
    766779        </ul> 
     
    769782    </ul> 
    770783 
    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 %} 
     784Let's walk through this example. ``{% regroup %}`` takes three arguments: the 
     785list you want to regroup, the attribute to group by, and the name of the 
     786resulting list. Here, we're regrouping the ``people`` list by the ``gender`` 
     787attribute 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 
     797Note that ``{% regroup %}`` does not order its input! Our example relies on 
     798the fact that the ``people`` list was ordered by ``gender`` in the first place. 
     799If the ``people`` list did *not* order its members by ``gender``, the regrouping 
     800would naively display more than one group for a single gender. For example, 
     801say the ``people`` list was set to this (note that the males are not grouped 
     802together):: 
     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 
     812With this input for ``people``, the example ``{% regroup %}`` template code 
     813above 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 
     826The easiest solution to this gotcha is to make sure in your view code that the 
     827data is ordered according to how you want to display it. 
     828 
     829Another solution is to sort the data in the template using the ``dictsort`` 
     830filter, if your data is in a list of dictionaries:: 
     831 
     832    {% regroup people|dictsort:"gender" by gender as gender_list %} 
    783833 
    784834spaceless 
     
    9661016~~~~~~~~ 
    9671017 
    968 Takes a list of dicts, returns that list sorted by the property given in the 
    969 argument. 
     1018Takes a list of dictionaries, returns that list sorted by the key given in 
     1019the argument. 
    9701020 
    9711021dictsortreversed 
    9721022~~~~~~~~~~~~~~~~ 
    9731023 
    974 Takes a list of dicts, returns that list sorted in reverse order by the 
    975 property given in the argument. 
     1024Takes a list of dictionaries, returns that list sorted in reverse order by the 
     1025key given in the argument. 
    9761026 
    9771027divisibleby