diff options
| author | Luke Plant <L.Plant.98@cantab.net> | 2011-06-02 16:18:47 +0000 |
|---|---|---|
| committer | Luke Plant <L.Plant.98@cantab.net> | 2011-06-02 16:18:47 +0000 |
| commit | 5434ce231d75004bdbe5cf2b7b24ce67a2a6e737 (patch) | |
| tree | 3e4943eff23623b97fb7423e119c4733eace8aaa /tests/regressiontests/admin_views | |
| parent | 78b37975c9d9f331b9ea9fa609d0596ae30ab6b4 (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.py | 14 | ||||
| -rw-r--r-- | tests/regressiontests/admin_views/tests.py | 85 |
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) |
