Ticket #11868: 11868.diff

File 11868.diff, 8.5 KB (added by jacob, 4 years ago)

Updated to trunk (r16060)

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

    diff --git a/django/contrib/admin/media/css/base.css b/django/contrib/admin/media/css/base.css
    index c5e385d..9a7a0f2 100644
    a b table thead th.descending a { 
    326326    background: url(../img/admin/arrow-down.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/templates/admin/change_list_results.html

    diff --git a/django/contrib/admin/templates/admin/change_list_results.html b/django/contrib/admin/templates/admin/change_list_results.html
    index b3fa224..2fd44c8 100644
    a b  
    88<table id="result_list">
    99<thead>
    1010<tr>
    11 {% for header in result_headers %}<th scope="col"{{ header.class_attrib }}>
    12 {% if header.sortable %}<a href="{{ header.url }}">{% endif %}
    13 {{ header.text|capfirst }}
    14 {% if header.sortable %}</a>{% endif %}</th>{% endfor %}
     11{% for header in result_headers %}
     12<th scope="col" {{ header.class_attrib }}>
     13  {% if header.sortable %}<a href="{{ header.url }}">{% endif %}
     14  <span class="text">{{ header.text|capfirst }}</span>
     15  {% if header.sortable %}<span class="sort_pos">{{ header.sort_pos }}</span>
     16  <span class="clear"></span>
     17  </a>{% endif %}
     18</th>{% endfor %}
    1519</tr>
    1620</thead>
    1721<tbody>
  • django/contrib/admin/templatetags/admin_list.py

    diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
    index fdf082b..3b34091 100644
    a b def result_headers(cl): 
    110110
    111111        th_classes = []
    112112        new_order_type = 'asc'
    113         if field_name == cl.order_field or admin_order_field == cl.order_field:
    114             th_classes.append('sorted %sending' % cl.order_type.lower())
    115             new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type.lower()]
     113        ordering_fields = cl.get_ordering_fields()
     114        sort_pos = ''
     115        if field_name in ordering_fields.keys() or admin_order_field in ordering_fields.keys():
     116            if not field_name in ordering_fields.keys():
     117                field_name = admin_order_field
     118            order_type = ordering_fields.get(field_name).lower()
     119            sort_pos = ordering_fields.keys().index(field_name) + 1
     120            th_classes.append('sorted %sending' % order_type)
     121            new_order_type = {'':'asc', 'asc': 'desc', 'desc': ''}[order_type]
     122
     123        # build new ordering param
     124        o_list = []
     125        for f in ordering_fields.keys():
     126            try:
     127                n = cl.list_display.index(f)
     128            except ValueError:
     129                continue
     130
     131            if f == field_name:
     132                if new_order_type == '':
     133                    continue
     134                t = new_order_type
     135            else:
     136                t = ordering_fields.get(f)
     137
     138            o_list.append((t=='desc' and '-' or '') + str(n))
     139
     140        if field_name not in ordering_fields.keys() and new_order_type:
     141            n = cl.list_display.index(field_name)
     142            o_list.append((new_order_type=='desc' and '-' or '') + str(n))
     143
     144        o_list = ','.join(o_list)
    116145
    117146        yield {
    118147            "text": header,
    119148            "sortable": True,
    120             "url": cl.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}),
     149            "sort_pos": sort_pos > 0 and len(ordering_fields) > 0 and unicode(sort_pos) or '',
     150            "url": cl.get_query_string({ORDER_VAR: o_list}),
    121151            "class_attrib": mark_safe(th_classes and ' class="%s"' % ' '.join(th_classes) or '')
    122152        }
    123153
  • django/contrib/admin/views/main.py

    diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
    index 170d168..b53806c 100644
    a b from django.contrib.admin.util import quote, get_fields_from_path 
    44from django.core.exceptions import SuspiciousOperation
    55from django.core.paginator import InvalidPage
    66from django.db import models
     7from django.db.models.query import QuerySet
     8from django.utils.datastructures import SortedDict
    79from django.utils.encoding import force_unicode, smart_str
    810from django.utils.translation import ugettext, ugettext_lazy
    911from django.utils.http import urlencode
    class ChangeList(object): 
    5961            self.list_editable = ()
    6062        else:
    6163            self.list_editable = list_editable
    62         self.order_field, self.order_type = self.get_ordering()
     64        self.ordering = self.get_ordering()
    6365        self.query = request.GET.get(SEARCH_VAR, '')
    6466        self.query_set = self.get_query_set()
    6567        self.get_results(request)
    class ChangeList(object): 
    136138        # manually-specified ordering from the query string.
    137139        ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
    138140
    139         if ordering[0].startswith('-'):
    140             order_field, order_type = ordering[0][1:], 'desc'
    141         else:
    142             order_field, order_type = ordering[0], 'asc'
    143141        if ORDER_VAR in params:
    144             try:
    145                 field_name = self.list_display[int(params[ORDER_VAR])]
     142            # Clear ordering and used params
     143            ordering = []
     144            order_params = params[ORDER_VAR].split(',')
     145            for p in order_params:
    146146                try:
    147                     f = lookup_opts.get_field(field_name)
    148                 except models.FieldDoesNotExist:
    149                     # See whether field_name is a name of a non-field
    150                     # that allows sorting.
     147                    none, pfx, idx = p.rpartition('-')
     148                    field_name = self.list_display[int(idx)]
    151149                    try:
    152                         if callable(field_name):
    153                             attr = field_name
    154                         elif hasattr(self.model_admin, field_name):
    155                             attr = getattr(self.model_admin, field_name)
    156                         else:
    157                             attr = getattr(self.model, field_name)
    158                         order_field = attr.admin_order_field
    159                     except AttributeError:
    160                         pass
    161                 else:
    162                     order_field = f.name
    163             except (IndexError, ValueError):
    164                 pass # Invalid ordering specified. Just use the default.
    165         if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
    166             order_type = params[ORDER_TYPE_VAR]
    167         return order_field, order_type
     150                        f = lookup_opts.get_field(field_name)
     151                    except models.FieldDoesNotExist:
     152                        # See whether field_name is a name of a non-field
     153                        # that allows sorting.
     154                        try:
     155                            if callable(field_name):
     156                                attr = field_name
     157                            elif hasattr(self.model_admin, field_name):
     158                                attr = getattr(self.model_admin, field_name)
     159                            else:
     160                                attr = getattr(self.model, field_name)
     161                            field_name = attr.admin_order_field
     162                        except AttributeError:
     163                            pass
     164                    else:
     165                        field_name = f.name
     166
     167                    ordering.append(pfx + field_name)
     168
     169                except (IndexError, ValueError):
     170                    pass # Invalid ordering specified. Skip it.
     171
     172        return ordering
     173
     174    def get_ordering_fields(self):
     175        # Returns a SortedDict of ordering fields and asc/desc
     176        ordering_fields = SortedDict()
     177        for o in self.ordering:
     178            none, t, f = o.rpartition('-')
     179            ordering_fields[f] = t == '-' and 'desc' or 'asc'
     180        return ordering_fields
    168181
    169182    def get_query_set(self):
    170183        use_distinct = False
    class ChangeList(object): 
    239252                            break
    240253
    241254        # Set ordering.
    242         if self.order_field:
    243             qs = qs.order_by('%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field))
     255        if self.ordering:
     256            qs = qs.order_by(*self.ordering)
    244257
    245258        # Apply keyword searches.
    246259        def construct_search(field_name):
Back to Top