Ticket #11868: admin-multisort-1.2-beta-SVN-12755.diff

File admin-multisort-1.2-beta-SVN-12755.diff, 8.5 KB (added by Ben Davis, 15 years ago)

Updated for 1.2-beta

  • django/contrib/admin/media/css/base.css

     
    326326    background: url(../img/admin/arrow-up.gif) right .4em no-repeat;
    327327}
    328328
     329table thead th.sorted a span.text {
     330   display: block;
     331   float: left;
     332}
     333table thead th.sorted a span.sort_pos {
     334   display: block;
     335   float: right;
     336   font-size: .6em;
     337}
     338table thead th.sorted a span.clear{
     339   display: block;
     340   clear: both;
     341}
     342
    329343/* ORDERABLE TABLES */
    330344
    331345table.orderable tbody tr td:hover {
  • django/contrib/admin/templatetags/admin_list.py

     
    103103
    104104        th_classes = []
    105105        new_order_type = 'asc'
    106         if field_name == cl.order_field or admin_order_field == cl.order_field:
    107             th_classes.append('sorted %sending' % cl.order_type.lower())
    108             new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type.lower()]
     106        ordering_fields = cl.get_ordering_fields()
     107        sort_pos = ''
     108        if field_name in ordering_fields.keys() or admin_order_field in ordering_fields.keys():
     109            if not field_name in ordering_fields.keys():
     110                field_name = admin_order_field
     111            order_type = ordering_fields.get(field_name).lower()
     112            sort_pos = ordering_fields.keys().index(field_name) + 1
     113            th_classes.append('sorted %sending' % order_type)
     114            new_order_type = {'':'asc', 'asc': 'desc', 'desc': ''}[order_type]
     115       
     116        # build new ordering param
     117        o_list = []
     118        for f in ordering_fields.keys():
     119            try:
     120                n = cl.list_display.index(f)
     121            except ValueError:
     122                continue
     123 
     124            if f == field_name:
     125                if new_order_type == '':
     126                    continue
     127                t = new_order_type
     128            else:
     129                t = ordering_fields.get(f)
    109130
     131            o_list.append((t=='desc' and '-' or '') + str(n))
     132       
     133        if field_name not in ordering_fields.keys() and new_order_type:
     134            n = cl.list_display.index(field_name)
     135            o_list.append((new_order_type=='desc' and '-' or '') + str(n))
     136
     137        o_list = ','.join(o_list)
     138
    110139        yield {
    111140            "text": header,
    112141            "sortable": True,
    113             "url": cl.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}),
     142            "sort_pos": sort_pos > 0 and len(ordering_fields) > 0 and unicode(sort_pos) or '',
     143            "url": cl.get_query_string({ORDER_VAR: o_list}),
    114144            "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '')
    115145        }
    116146
  • django/contrib/admin/views/main.py

     
    44from django.core.paginator import Paginator, InvalidPage
    55from django.db import models
    66from django.db.models.query import QuerySet
     7from django.utils.datastructures import SortedDict
    78from django.utils.encoding import force_unicode, smart_str
    89from django.utils.translation import ugettext
    910from django.utils.http import urlencode
     
    6364        if ERROR_FLAG in self.params:
    6465            del self.params[ERROR_FLAG]
    6566
    66         self.order_field, self.order_type = self.get_ordering()
     67        self.ordering = self.get_ordering()
    6768        self.query = request.GET.get(SEARCH_VAR, '')
    6869        self.query_set = self.get_query_set()
    6970        self.get_results(request)
     
    137138        # those exist, order descending by ID by default. Finally, look for
    138139        # manually-specified ordering from the query string.
    139140        ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
    140 
    141         if ordering[0].startswith('-'):
    142             order_field, order_type = ordering[0][1:], 'desc'
    143         else:
    144             order_field, order_type = ordering[0], 'asc'
     141       
    145142        if ORDER_VAR in params:
    146             try:
    147                 field_name = self.list_display[int(params[ORDER_VAR])]
     143            # Clear ordering and used params
     144            ordering = []
     145            order_params = params[ORDER_VAR].split(',')
     146            for p in order_params:
    148147                try:
    149                     f = lookup_opts.get_field(field_name)
    150                 except models.FieldDoesNotExist:
    151                     # See whether field_name is a name of a non-field
    152                     # that allows sorting.
     148                    none, pfx, idx = p.rpartition('-')
     149                    field_name = self.list_display[int(idx)]
    153150                    try:
    154                         if callable(field_name):
    155                             attr = field_name
    156                         elif hasattr(self.model_admin, field_name):
    157                             attr = getattr(self.model_admin, field_name)
    158                         else:
    159                             attr = getattr(self.model, field_name)
    160                         order_field = attr.admin_order_field
    161                     except AttributeError:
    162                         pass
    163                 else:
    164                     order_field = f.name
    165             except (IndexError, ValueError):
    166                 pass # Invalid ordering specified. Just use the default.
    167         if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
    168             order_type = params[ORDER_TYPE_VAR]
    169         return order_field, order_type
     151                        f = lookup_opts.get_field(field_name)
     152                    except models.FieldDoesNotExist:
     153                        # See whether field_name is a name of a non-field
     154                        # that allows sorting.
     155                        try:
     156                            if callable(field_name):
     157                                attr = field_name
     158                            elif hasattr(self.model_admin, field_name):
     159                                attr = getattr(self.model_admin, field_name)
     160                            else:
     161                                attr = getattr(self.model, field_name)
     162                            field_name = attr.admin_order_field
     163                        except AttributeError:
     164                            pass
     165                    else:
     166                        field_name = f.name
    170167
     168                    ordering.append(pfx + field_name)
     169
     170                except (IndexError, ValueError):
     171                    pass # Invalid ordering specified. Skip it.
     172
     173        return ordering
     174   
     175    def get_ordering_fields(self):
     176        # Returns a SortedDict of ordering fields and asc/desc
     177        ordering_fields = SortedDict()
     178        for o in self.ordering:
     179            none, t, f = o.rpartition('-')
     180            ordering_fields[f] = t == '-' and 'desc' or 'asc'
     181        return ordering_fields
     182
    171183    def get_query_set(self):
    172184        qs = self.root_query_set
    173185        lookup_params = self.params.copy() # a dictionary of the query string
     
    214226                            break
    215227
    216228        # Set ordering.
    217         if self.order_field:
    218             qs = qs.order_by('%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field))
     229        if self.ordering:
     230            qs = qs.order_by(*self.ordering)
    219231
    220232        # Apply keyword searches.
    221233        def construct_search(field_name):
  • django/contrib/admin/templates/admin/change_list_results.html

     
    22<table cellspacing="0">
    33<thead>
    44<tr>
    5 {% for header in result_headers %}<th{{ header.class_attrib }}>
    6 {% if header.sortable %}<a href="{{ header.url }}">{% endif %}
    7 {{ header.text|capfirst }}
    8 {% if header.sortable %}</a>{% endif %}</th>{% endfor %}
     5{% for header in result_headers %}
     6<th{{ header.class_attrib }}>
     7  {% if header.sortable %}<a href="{{ header.url }}">{% endif %}
     8  <span class="text">{{ header.text|capfirst }}</span>
     9  {% if header.sortable %}<span class="sort_pos">{{ header.sort_pos }}</span>
     10  <span class="clear"></span>
     11  </a>{% endif %}
     12</th>{% endfor %}
    913</tr>
    1014</thead>
    1115<tbody>
Back to Top