Ticket #14977: admin_multi_ordering.patch

File admin_multi_ordering.patch, 5.0 KB (added by Florian Sening, 13 years ago)

updated patch for 1.3 trunk

  • django/contrib/admin/templatetags/admin_list.py

     
    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        if field_name == cl.order_field[0] or admin_order_field == cl.order_field[0]:
     114            th_classes.append('sorted %sending' % cl.order_type[0].lower())
     115            new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type[0].lower()]
    116116
    117117        yield {
    118118            "text": header,
  • django/contrib/admin/views/main.py

     
    130130
    131131    def get_ordering(self):
    132132        lookup_opts, params = self.lookup_opts, self.params
    133         # For ordering, first check the "ordering" parameter in the admin
    134         # options, then check the object's default ordering. If neither of
    135         # those exist, order descending by ID by default. Finally, look for
    136         # manually-specified ordering from the query string.
    137         ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
     133        # For ordering, first check manually-specified ordering from the query
     134        # string and let this override all other orderings. If there is no
     135        # manually-specified ordering check the "ordering" parameter in the
     136        # admin options, then check the object's default ordering. If neither
     137        # of those exist, order descending by ID by default.
    138138
    139         if ordering[0].startswith('-'):
    140             order_field, order_type = ordering[0][1:], 'desc'
    141         else:
    142             order_field, order_type = ordering[0], 'asc'
    143         if ORDER_VAR in params:
     139        # Support multiple orderings by having order_field and order_type be
     140        # lists such that order_field[i] and order_type[i] are corresponding
     141        # order_field and order_type values.
     142
     143        order_field = []
     144        order_type = []
     145        # Check for manually-specified ordering from query string.
     146        if ORDER_VAR in params and ORDER_TYPE_VAR in params:
    144147            try:
     148
     149                # Get order_type. If order_type is not 'asc' or 'desc' then
     150                # raise ValueError to 'get out' of try block and use default
     151                # ordering.
     152                if params[ORDER_TYPE_VAR] in ('asc', 'desc'):
     153                    order_type.append(params[ORDER_TYPE_VAR])
     154                else:
     155                    raise ValueError
     156
     157                # Get order_field
    145158                field_name = self.list_display[int(params[ORDER_VAR])]
    146159                try:
    147160                    f = lookup_opts.get_field(field_name)
     
    155168                            attr = getattr(self.model_admin, field_name)
    156169                        else:
    157170                            attr = getattr(self.model, field_name)
    158                         order_field = attr.admin_order_field
     171                        order_field.append(attr.admin_order_field)
    159172                    except AttributeError:
    160173                        pass
    161174                else:
    162                     order_field = f.name
     175                    order_field.append(f.name)
     176
    163177            except (IndexError, ValueError):
    164178                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]
     179
     180        if not order_field or not order_type:
     181            # Get ordering from "ordering" parameter in the admin options,
     182            # object's default ordering, or by ID descending.
     183            ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
     184            for i in range(len(ordering)):
     185                if ordering[i].startswith('-'):
     186                    order_field.append(ordering[i][1:])
     187                    order_type.append('desc')
     188                else:
     189                    order_field.append(ordering[i])
     190                    order_type.append('asc')
     191
    167192        return order_field, order_type
    168193
    169194    def get_query_set(self):
     
    240265
    241266        # Set ordering.
    242267        if self.order_field:
    243             qs = qs.order_by('%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field))
     268            ordering = ['%s%s' % ((self.order_type[i] == 'desc' and '-' or ''),
     269                self.order_field[i]) for i in range(len(self.order_field))]
     270            qs = qs.order_by(*ordering)
    244271
    245272        # Apply keyword searches.
    246273        def construct_search(field_name):
Back to Top