Ticket #11695: change_list_sort.diff

File change_list_sort.diff, 8.4 KB (added by Joshua Russo, 15 years ago)

with testing and docs

  • django/contrib/admin/templates/admin/change_list.html

     
    4141    {% block object-tools %}
    4242      {% if has_add_permission %}
    4343        <ul class="object-tools">
     44          <li><a href=".">
     45                {% if cl.has_filters or cl.date_hierarchy %}
     46                        {% trans 'Reset sorting and filters' %}
     47                {% else %}
     48                        {% trans 'Reset sorting' %}
     49                {% endif %}
     50          </a></li>
    4451          <li>
    4552            <a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">
    4653              {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
  • django/contrib/admin/templatetags/admin_list.py

     
    120120
    121121        th_classes = []
    122122        new_order_type = 'asc'
    123         if field_name == cl.order_field or admin_order_field == cl.order_field:
     123        if cl.order_field is not None and (field_name == cl.order_field or admin_order_field == cl.order_field):
    124124            th_classes.append('sorted %sending' % cl.order_type.lower())
    125125            new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type.lower()]
    126126
  • django/contrib/admin/views/main.py

     
    6363        if ERROR_FLAG in self.params:
    6464            del self.params[ERROR_FLAG]
    6565
    66         self.order_field, self.order_type = self.get_ordering()
     66        self.order_field, self.order_type, self.ordering = self.get_ordering()
    6767        self.query = request.GET.get(SEARCH_VAR, '')
    6868        self.query_set = self.get_query_set()
    6969        self.get_results(request)
     
    138138        # manually-specified ordering from the query string.
    139139        ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
    140140
    141         if ordering[0].startswith('-'):
    142             order_field, order_type = ordering[0][1:], 'desc'
     141        if len(ordering) == 1:
     142            if ordering[0].startswith('-'):
     143                order_field, order_type = ordering[0][1:], 'desc'
     144            else:
     145                order_field, order_type = ordering[0], 'asc'
    143146        else:
    144             order_field, order_type = ordering[0], 'asc'
     147            order_field = None
     148            order_type = None
    145149        if ORDER_VAR in params:
    146150            try:
    147151                field_name = self.list_display[int(params[ORDER_VAR])]
     
    166170                pass # Invalid ordering specified. Just use the default.
    167171        if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
    168172            order_type = params[ORDER_TYPE_VAR]
    169         return order_field, order_type
     173        return order_field, order_type, ordering
    170174
    171175    def get_query_set(self):
    172176        qs = self.root_query_set
     
    216220        # Set ordering.
    217221        if self.order_field:
    218222            qs = qs.order_by('%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field))
     223        elif self.ordering:
     224            qs = qs.order_by(*self.ordering)
    219225
    220226        # Apply keyword searches.
    221227        def construct_search(field_name):
  • docs/ref/contrib/admin/index.txt

     
    492492
    493493    Django will only honor the first element in the list/tuple; any others
    494494    will be ignored.
     495   
     496.. versionadded:: 1.2
    495497
     498    Django will now honor the entire list/tuple specified in the ``ordering``
     499    attribute, but only for the initial display of the list. After the change
     500    list page is displayed, if a column is selected by the user for sorting
     501    only that column will be used. The ``Reset Sorting`` link can be used to
     502    bring the list back to the initial sorting.
     503   
    496504.. attribute:: ModelAdmin.prepopulated_fields
    497505
    498506Set ``prepopulated_fields`` to a dictionary mapping field names to the fields
  • tests/regressiontests/admin_changelist/models.py

     
    66
    77class Child(models.Model):
    88    parent = models.ForeignKey(Parent, editable=False)
    9     name = models.CharField(max_length=30, blank=True)
    10  No newline at end of file
     9    name = models.CharField(max_length=30, blank=True)
     10   
     11    class Meta: 
     12        # This is to test the default ordering in the ChangeList     
     13        ordering = ["parent", "name"]
     14 No newline at end of file
  • tests/regressiontests/admin_changelist/tests.py

     
    1414                m.list_filter,m.date_hierarchy, m.search_fields,
    1515                m.list_select_related, m.list_per_page, m.list_editable, m)
    1616        self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}})
     17       
     18    def test_model_order_used(self):
     19        """
     20        The ChangeList should initially use the sort order specified in the model
     21        """
     22        m = ChildAdmin(Child, admin.site)
     23        cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links,
     24                m.list_filter,m.date_hierarchy, m.search_fields,
     25                m.list_select_related, m.list_per_page, m.list_editable, m)
     26        self.assert_(cl.query_set.query.order_by == Child._meta.ordering, "The model sort order was not properly applied.")
    1727
    1828class ChildAdmin(admin.ModelAdmin):
    1929    list_display = ['name', 'parent']
  • tests/regressiontests/admin_views/models.py

     
    2222    date = models.DateTimeField()
    2323    section = models.ForeignKey(Section)
    2424
     25    class Meta:
     26        # This is to test the default ordering in the ChangeList
     27        ordering = ['section', 'content']
     28
    2529    def __unicode__(self):
    2630        return self.title
    2731
  • tests/regressiontests/admin_views/tests.py

     
    164164        Ensure we can sort on a list_display field that is a Model method
    165165        (colunn 3 is 'model_year' in ArticleAdmin)
    166166        """
    167         response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'dsc', 'o': 3})
     167        response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'desc', 'o': 3})
    168168        self.failUnlessEqual(response.status_code, 200)
    169169        self.failUnless(
    170170            response.content.index('Newest content') < response.content.index('Middle content') and
     
    185185            "Results of sorting on ModelAdmin method are out of order."
    186186        )
    187187
     188    def testChangeListSortingModelDefault(self):
     189        """Ensure the default ordering is used from the model"""
     190        response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit)
     191        self.failUnlessEqual(response.status_code, 200)
     192        self.failUnless(
     193            response.content.index('Middle content') < response.content.index('Newest content') and
     194            response.content.index('Newest content') < response.content.index('Oldest content'),
     195            "Results of sorting on Model default sort are out of order."
     196        )
     197
    188198    def testLimitedFilter(self):
    189199        """Ensure admin changelist filters do not contain objects excluded via limit_choices_to."""
    190200        response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit)
Back to Top