summaryrefslogtreecommitdiff
path: root/tests/regressiontests/admin_views
diff options
context:
space:
mode:
authorLuke Plant <L.Plant.98@cantab.net>2011-06-02 16:18:47 +0000
committerLuke Plant <L.Plant.98@cantab.net>2011-06-02 16:18:47 +0000
commit5434ce231d75004bdbe5cf2b7b24ce67a2a6e737 (patch)
tree3e4943eff23623b97fb7423e119c4733eace8aaa /tests/regressiontests/admin_views
parent78b37975c9d9f331b9ea9fa609d0596ae30ab6b4 (diff)
Fixed #11868 - Multiple sort in admin changelist.
Many thanks to bendavis78 for the initial patch, and for input from others. Also fixed #7309. If people were relying on the undocumented default ordering applied by the admin before, they will need to add 'ordering = ["-pk"]' to their ModelAdmin. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16316 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests/admin_views')
-rw-r--r--tests/regressiontests/admin_views/models.py14
-rw-r--r--tests/regressiontests/admin_views/tests.py85
2 files changed, 90 insertions, 9 deletions
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index 854fb60e70..98873966eb 100644
--- a/tests/regressiontests/admin_views/models.py
+++ b/tests/regressiontests/admin_views/models.py
@@ -243,9 +243,6 @@ class Person(models.Model):
def __unicode__(self):
return self.name
- class Meta:
- ordering = ["id"]
-
class BasePersonModelFormSet(BaseModelFormSet):
def clean(self):
for person_dict in self.cleaned_data:
@@ -259,13 +256,17 @@ class PersonAdmin(admin.ModelAdmin):
list_editable = ('gender', 'alive')
list_filter = ('gender',)
search_fields = ('^name',)
- ordering = ["id"]
save_as = True
def get_changelist_formset(self, request, **kwargs):
return super(PersonAdmin, self).get_changelist_formset(request,
formset=BasePersonModelFormSet, **kwargs)
+ def queryset(self, request):
+ # Order by a field that isn't in list display, to be able to test
+ # whether ordering is preserved.
+ return super(PersonAdmin, self).queryset(request).order_by('age')
+
class Persona(models.Model):
"""
@@ -357,6 +358,9 @@ class Media(models.Model):
class Podcast(Media):
release_date = models.DateField()
+ class Meta:
+ ordering = ('release_date',) # overridden in PodcastAdmin
+
class PodcastAdmin(admin.ModelAdmin):
list_display = ('name', 'release_date')
list_editable = ('release_date',)
@@ -795,6 +799,7 @@ class StoryAdmin(admin.ModelAdmin):
list_display_links = ('title',) # 'id' not in list_display_links
list_editable = ('content', )
form = StoryForm
+ ordering = ["-pk"]
class OtherStory(models.Model):
title = models.CharField(max_length=100)
@@ -804,6 +809,7 @@ class OtherStoryAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'content')
list_display_links = ('title', 'id') # 'id' in list_display_links
list_editable = ('content', )
+ ordering = ["-pk"]
admin.site.register(Article, ArticleAdmin)
admin.site.register(CustomArticle, CustomArticleAdmin)
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 7c6cdd4944..4361dc992e 100644
--- a/tests/regressiontests/admin_views/tests.py
+++ b/tests/regressiontests/admin_views/tests.py
@@ -32,7 +32,7 @@ from django.utils import unittest
# local test models
from models import (Article, BarAccount, CustomArticle, EmptyModel,
- FooAccount, Gallery, GalleryAdmin, ModelWithStringPrimaryKey,
+ FooAccount, Gallery, PersonAdmin, ModelWithStringPrimaryKey,
Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast,
Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit,
Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee,
@@ -204,7 +204,7 @@ class AdminViewBasicTest(TestCase):
Ensure we can sort on a list_display field that is a callable
(column 2 is callable_year in ArticleAdmin)
"""
- response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'asc', 'o': 2})
+ response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': 2})
self.assertEqual(response.status_code, 200)
self.assertTrue(
response.content.index('Oldest content') < response.content.index('Middle content') and
@@ -217,7 +217,7 @@ class AdminViewBasicTest(TestCase):
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, {'o': '-3'})
self.assertEqual(response.status_code, 200)
self.assertTrue(
response.content.index('Newest content') < response.content.index('Middle content') and
@@ -230,7 +230,7 @@ class AdminViewBasicTest(TestCase):
Ensure we can sort on a list_display field that is a ModelAdmin method
(colunn 4 is 'modeladmin_year' in ArticleAdmin)
"""
- response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'ot': 'asc', 'o': 4})
+ response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit, {'o': '4'})
self.assertEqual(response.status_code, 200)
self.assertTrue(
response.content.index('Oldest content') < response.content.index('Middle content') and
@@ -238,6 +238,81 @@ class AdminViewBasicTest(TestCase):
"Results of sorting on ModelAdmin method are out of order."
)
+ def testChangeListSortingMultiple(self):
+ p1 = Person.objects.create(name="Chris", gender=1, alive=True)
+ p2 = Person.objects.create(name="Chris", gender=2, alive=True)
+ p3 = Person.objects.create(name="Bob", gender=1, alive=True)
+ link = '<a href="%s/'
+
+ # Sort by name, gender
+ # This hard-codes the URL because it'll fail if it runs against the
+ # 'admin2' custom admin (which doesn't have the Person model).
+ response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '1.2'})
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue(
+ response.content.index(link % p3.id) < response.content.index(link % p1.id) and
+ response.content.index(link % p1.id) < response.content.index(link % p2.id)
+ )
+
+ # Sort by gender descending, name
+ response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '-2.1'})
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue(
+ response.content.index(link % p2.id) < response.content.index(link % p3.id) and
+ response.content.index(link % p3.id) < response.content.index(link % p1.id)
+ )
+
+ def testChangeListSortingPreserveQuerySetOrdering(self):
+ # If no ordering on ModelAdmin, or query string, the underlying order of
+ # the queryset should not be changed.
+
+ p1 = Person.objects.create(name="Amy", gender=1, alive=True, age=80)
+ p2 = Person.objects.create(name="Bob", gender=1, alive=True, age=70)
+ p3 = Person.objects.create(name="Chris", gender=2, alive=False, age=60)
+ link = '<a href="%s/'
+
+ # This hard-codes the URL because it'll fail if it runs against the
+ # 'admin2' custom admin (which doesn't have the Person model).
+ response = self.client.get('/test_admin/admin/admin_views/person/', {})
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue(
+ response.content.index(link % p3.id) < response.content.index(link % p2.id) and
+ response.content.index(link % p2.id) < response.content.index(link % p1.id)
+ )
+
+ def testChangeListSortingModelMeta(self):
+ # Test ordering on Model Meta is respected
+
+ l1 = Language.objects.create(iso='ur', name='Urdu')
+ l2 = Language.objects.create(iso='ar', name='Arabic')
+ link = '<a href="%s/'
+
+ response = self.client.get('/test_admin/admin/admin_views/language/', {})
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue(
+ response.content.index(link % l2.pk) < response.content.index(link % l1.pk)
+ )
+
+ # Test we can override with query string
+ response = self.client.get('/test_admin/admin/admin_views/language/', {'o':'-1'})
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue(
+ response.content.index(link % l1.pk) < response.content.index(link % l2.pk)
+ )
+
+ def testChangeListSortingModelAdmin(self):
+ # Test ordering on Model Admin is respected, and overrides Model Meta
+ dt = datetime.datetime.now()
+ p1 = Podcast.objects.create(name="A", release_date=dt)
+ p2 = Podcast.objects.create(name="B", release_date=dt - datetime.timedelta(10))
+
+ link = '<a href="%s/'
+ response = self.client.get('/test_admin/admin/admin_views/podcast/', {})
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue(
+ response.content.index(link % p1.pk) < response.content.index(link % p2.pk)
+ )
+
def testLimitedFilter(self):
"""Ensure admin changelist filters do not contain objects excluded via limit_choices_to.
This also tests relation-spanning filters (e.g. 'color__value').
@@ -1956,7 +2031,7 @@ class AdminActionsTest(TestCase):
'action' : 'external_mail',
'index': 0,
}
- url = '/test_admin/admin/admin_views/externalsubscriber/?ot=asc&o=1'
+ url = '/test_admin/admin/admin_views/externalsubscriber/?o=1'
response = self.client.post(url, action_data)
self.assertRedirects(response, url)