Index: django/contrib/admin/templates/admin/change_list.html
===================================================================
--- django/contrib/admin/templates/admin/change_list.html	(revision 11585)
+++ django/contrib/admin/templates/admin/change_list.html	(working copy)
@@ -41,6 +41,13 @@
     {% block object-tools %}
       {% if has_add_permission %}
         <ul class="object-tools">
+          <li><a href=".">
+          	{% if cl.has_filters or cl.date_hierarchy %}
+          		{% trans 'Reset sorting and filters' %}
+          	{% else %}
+          		{% trans 'Reset sorting' %}
+          	{% endif %}
+          </a></li>
           <li>
             <a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">
               {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
Index: django/contrib/admin/templatetags/admin_list.py
===================================================================
--- django/contrib/admin/templatetags/admin_list.py	(revision 11585)
+++ django/contrib/admin/templatetags/admin_list.py	(working copy)
@@ -120,7 +120,7 @@
 
         th_classes = []
         new_order_type = 'asc'
-        if field_name == cl.order_field or admin_order_field == cl.order_field:
+        if cl.order_field is not None and (field_name == cl.order_field or admin_order_field == cl.order_field):
             th_classes.append('sorted %sending' % cl.order_type.lower())
             new_order_type = {'asc': 'desc', 'desc': 'asc'}[cl.order_type.lower()]
 
Index: django/contrib/admin/views/main.py
===================================================================
--- django/contrib/admin/views/main.py	(revision 11585)
+++ django/contrib/admin/views/main.py	(working copy)
@@ -63,7 +63,7 @@
         if ERROR_FLAG in self.params:
             del self.params[ERROR_FLAG]
 
-        self.order_field, self.order_type = self.get_ordering()
+        self.order_field, self.order_type, self.ordering = self.get_ordering()
         self.query = request.GET.get(SEARCH_VAR, '')
         self.query_set = self.get_query_set()
         self.get_results(request)
@@ -138,10 +138,14 @@
         # manually-specified ordering from the query string.
         ordering = self.model_admin.ordering or lookup_opts.ordering or ['-' + lookup_opts.pk.name]
 
-        if ordering[0].startswith('-'):
-            order_field, order_type = ordering[0][1:], 'desc'
+        if len(ordering) == 1:
+            if ordering[0].startswith('-'): 
+                order_field, order_type = ordering[0][1:], 'desc' 
+            else: 
+                order_field, order_type = ordering[0], 'asc'
         else:
-            order_field, order_type = ordering[0], 'asc'
+            order_field = None
+            order_type = None
         if ORDER_VAR in params:
             try:
                 field_name = self.list_display[int(params[ORDER_VAR])]
@@ -166,7 +170,7 @@
                 pass # Invalid ordering specified. Just use the default.
         if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
             order_type = params[ORDER_TYPE_VAR]
-        return order_field, order_type
+        return order_field, order_type, ordering
 
     def get_query_set(self):
         qs = self.root_query_set
@@ -216,6 +220,8 @@
         # Set ordering.
         if self.order_field:
             qs = qs.order_by('%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field))
+        elif self.ordering:
+            qs = qs.order_by(*self.ordering)
 
         # Apply keyword searches.
         def construct_search(field_name):
Index: docs/ref/contrib/admin/index.txt
===================================================================
--- docs/ref/contrib/admin/index.txt	(revision 11585)
+++ docs/ref/contrib/admin/index.txt	(working copy)
@@ -492,7 +492,15 @@
 
     Django will only honor the first element in the list/tuple; any others
     will be ignored.
+    
+.. versionadded:: 1.2
 
+    Django will now honor the entire list/tuple specified in the ``ordering``
+    attribute, but only for the initial display of the list. After the change
+    list page is displayed, if a column is selected by the user for sorting 
+    only that column will be used. The ``Reset Sorting`` link can be used to 
+    bring the list back to the initial sorting.
+    
 .. attribute:: ModelAdmin.prepopulated_fields
 
 Set ``prepopulated_fields`` to a dictionary mapping field names to the fields
Index: tests/regressiontests/admin_changelist/models.py
===================================================================
--- tests/regressiontests/admin_changelist/models.py	(revision 11585)
+++ tests/regressiontests/admin_changelist/models.py	(working copy)
@@ -6,4 +6,8 @@
 
 class Child(models.Model):
     parent = models.ForeignKey(Parent, editable=False)
-    name = models.CharField(max_length=30, blank=True)
\ No newline at end of file
+    name = models.CharField(max_length=30, blank=True)
+    
+    class Meta:  
+        # This is to test the default ordering in the ChangeList      
+        ordering = ["parent", "name"]
\ No newline at end of file
Index: tests/regressiontests/admin_changelist/tests.py
===================================================================
--- tests/regressiontests/admin_changelist/tests.py	(revision 11585)
+++ tests/regressiontests/admin_changelist/tests.py	(working copy)
@@ -14,6 +14,16 @@
                 m.list_filter,m.date_hierarchy, m.search_fields, 
                 m.list_select_related, m.list_per_page, m.list_editable, m)
         self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}})
+        
+    def test_model_order_used(self):
+        """
+        The ChangeList should initially use the sort order specified in the model
+        """
+        m = ChildAdmin(Child, admin.site)
+        cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links, 
+                m.list_filter,m.date_hierarchy, m.search_fields, 
+                m.list_select_related, m.list_per_page, m.list_editable, m)
+        self.assert_(cl.query_set.query.order_by == Child._meta.ordering, "The model sort order was not properly applied.")
 
 class ChildAdmin(admin.ModelAdmin):
     list_display = ['name', 'parent']
Index: tests/regressiontests/admin_views/models.py
===================================================================
--- tests/regressiontests/admin_views/models.py	(revision 11585)
+++ tests/regressiontests/admin_views/models.py	(working copy)
@@ -22,6 +22,10 @@
     date = models.DateTimeField()
     section = models.ForeignKey(Section)
 
+    class Meta:
+        # This is to test the default ordering in the ChangeList
+        ordering = ['section', 'content']
+
     def __unicode__(self):
         return self.title
 
Index: tests/regressiontests/admin_views/tests.py
===================================================================
--- tests/regressiontests/admin_views/tests.py	(revision 11585)
+++ tests/regressiontests/admin_views/tests.py	(working copy)
@@ -164,7 +164,7 @@
         Ensure we can sort on a list_display field that is a Model method
         (colunn 3 is 'model_year' in ArticleAdmin)
         """
-        response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'dsc', 'o': 3})
+        response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'desc', 'o': 3})
         self.failUnlessEqual(response.status_code, 200)
         self.failUnless(
             response.content.index('Newest content') < response.content.index('Middle content') and
@@ -185,6 +185,16 @@
             "Results of sorting on ModelAdmin method are out of order."
         )
 
+    def testChangeListSortingModelDefault(self):
+        """Ensure the default ordering is used from the model"""
+        response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit)
+        self.failUnlessEqual(response.status_code, 200)
+        self.failUnless(
+            response.content.index('Middle content') < response.content.index('Newest content') and
+            response.content.index('Newest content') < response.content.index('Oldest content'),
+            "Results of sorting on Model default sort are out of order."
+        )
+
     def testLimitedFilter(self):
         """Ensure admin changelist filters do not contain objects excluded via limit_choices_to."""
         response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit)
