diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 616b249..4eed016 100644
a
|
b
|
class ChangeList(object):
|
221 | 221 | # for ordering specified on ModelAdmin or model Meta, we don't know |
222 | 222 | # the right column numbers absolutely, because there might be more |
223 | 223 | # than one column associated with that ordering, so we guess. |
224 | | for f in ordering: |
225 | | if f.startswith('-'): |
226 | | f = f[1:] |
| 224 | for field in ordering: |
| 225 | if field.startswith('-'): |
| 226 | field = field[1:] |
227 | 227 | order_type = 'desc' |
228 | 228 | else: |
229 | 229 | order_type = 'asc' |
230 | | i = None |
| 230 | index = None |
231 | 231 | try: |
232 | 232 | # Search for simply field name first |
233 | | i = self.list_display.index(f) |
| 233 | index = list(self.list_display).index(field) |
234 | 234 | except ValueError: |
235 | | # No match, but their might be a match if we take into account |
236 | | # 'admin_order_field' |
237 | | for j, attr in enumerate(self.list_display): |
238 | | if getattr(attr, 'admin_order_field', '') == f: |
239 | | i = j |
| 235 | # No match, but there might be a match if we take into |
| 236 | # account 'admin_order_field' |
| 237 | for _index, attr in enumerate(self.list_display): |
| 238 | if getattr(attr, 'admin_order_field', '') == field: |
| 239 | index = _index |
240 | 240 | break |
241 | | if i is not None: |
242 | | ordering_fields[i] = order_type |
| 241 | if index is not None: |
| 242 | ordering_fields[index] = order_type |
243 | 243 | else: |
244 | 244 | for p in self.params[ORDER_VAR].split('.'): |
245 | 245 | none, pfx, idx = p.rpartition('-') |
diff --git a/tests/regressiontests/admin_changelist/admin.py b/tests/regressiontests/admin_changelist/admin.py
index d1d8e0f..80bb732 100644
a
|
b
|
from django.contrib import admin
|
4 | 4 | from django.core.paginator import Paginator |
5 | 5 | |
6 | 6 | from .models import (Child, Parent, Genre, Band, Musician, Group, Quartet, |
7 | | Membership, ChordsMusician, ChordsBand, Invitation) |
| 7 | Membership, ChordsMusician, ChordsBand, Invitation, Swallow) |
8 | 8 | |
9 | 9 | |
10 | 10 | site = admin.AdminSite(name="admin") |
… |
… |
class DynamicListDisplayLinksChildAdmin(admin.ModelAdmin):
|
75 | 75 | return ['age'] |
76 | 76 | |
77 | 77 | site.register(Child, DynamicListDisplayChildAdmin) |
| 78 | |
| 79 | class SwallowAdmin(admin.ModelAdmin): |
| 80 | actions = None # prevent ['action_checkbox'] + list(list_display) |
| 81 | list_display = ('origin', 'load', 'speed') |
| 82 | |
| 83 | site.register(Swallow, SwallowAdmin) |
diff --git a/tests/regressiontests/admin_changelist/models.py b/tests/regressiontests/admin_changelist/models.py
index eed3f68..97080fb 100644
a
|
b
|
class Invitation(models.Model):
|
49 | 49 | player = models.ForeignKey(ChordsMusician) |
50 | 50 | band = models.ForeignKey(ChordsBand) |
51 | 51 | instrument = models.CharField(max_length=15) |
| 52 | |
| 53 | class Swallow(models.Model): |
| 54 | origin = models.CharField(max_length=255) |
| 55 | load = models.FloatField() |
| 56 | speed = models.FloatField() |
| 57 | |
| 58 | class Meta: |
| 59 | ordering = ('speed', 'load') |
diff --git a/tests/regressiontests/admin_changelist/tests.py b/tests/regressiontests/admin_changelist/tests.py
index 9292895..b422519 100644
a
|
b
|
from django.test.client import RequestFactory
|
11 | 11 | from .admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin, |
12 | 12 | GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin, |
13 | 13 | DynamicListDisplayLinksChildAdmin, CustomPaginationAdmin, |
14 | | FilteredChildAdmin, CustomPaginator, site as custom_site) |
| 14 | FilteredChildAdmin, CustomPaginator, site as custom_site, |
| 15 | SwallowAdmin) |
15 | 16 | from .models import (Child, Parent, Genre, Band, Musician, Group, Quartet, |
16 | | Membership, ChordsMusician, ChordsBand, Invitation) |
| 17 | Membership, ChordsMusician, ChordsBand, Invitation, Swallow) |
17 | 18 | |
18 | 19 | |
19 | 20 | class ChangeListTests(TestCase): |
… |
… |
class ChangeListTests(TestCase):
|
22 | 23 | def setUp(self): |
23 | 24 | self.factory = RequestFactory() |
24 | 25 | |
| 26 | def _create_superuser(self, username): |
| 27 | return User.objects.create(username=username, is_superuser=True) |
| 28 | |
| 29 | def _mocked_authenticated_request(self, url, user): |
| 30 | request = self.factory.get(url) |
| 31 | request.user = user |
| 32 | return request |
| 33 | |
25 | 34 | def test_select_related_preserved(self): |
26 | 35 | """ |
27 | 36 | Regression test for #10348: ChangeList.get_query_set() shouldn't |
… |
… |
class ChangeListTests(TestCase):
|
323 | 332 | for i in range(10): |
324 | 333 | Child.objects.create(name='child %s' % i, parent=parent) |
325 | 334 | |
326 | | user_noparents = User.objects.create( |
327 | | username='noparents', |
328 | | is_superuser=True) |
329 | | user_parents = User.objects.create( |
330 | | username='parents', |
331 | | is_superuser=True) |
332 | | |
333 | | def _mocked_authenticated_request(user): |
334 | | request = self.factory.get('/child/') |
335 | | request.user = user |
336 | | return request |
| 335 | user_noparents = self._create_superuser('noparents') |
| 336 | user_parents = self._create_superuser('parents') |
337 | 337 | |
338 | 338 | # Test with user 'noparents' |
339 | 339 | m = custom_site._registry[Child] |
340 | | request = _mocked_authenticated_request(user_noparents) |
| 340 | request = self._mocked_authenticated_request('/child/', user_noparents) |
341 | 341 | response = m.changelist_view(request) |
342 | 342 | self.assertNotContains(response, 'Parent object') |
343 | 343 | |
… |
… |
class ChangeListTests(TestCase):
|
348 | 348 | |
349 | 349 | # Test with user 'parents' |
350 | 350 | m = DynamicListDisplayChildAdmin(Child, admin.site) |
351 | | request = _mocked_authenticated_request(user_parents) |
| 351 | request = self._mocked_authenticated_request('/child/', user_parents) |
352 | 352 | response = m.changelist_view(request) |
353 | 353 | self.assertContains(response, 'Parent object') |
354 | 354 | |
… |
… |
class ChangeListTests(TestCase):
|
362 | 362 | # Test default implementation |
363 | 363 | custom_site.register(Child, ChildAdmin) |
364 | 364 | m = custom_site._registry[Child] |
365 | | request = _mocked_authenticated_request(user_noparents) |
| 365 | request = self._mocked_authenticated_request('/child/', user_noparents) |
366 | 366 | response = m.changelist_view(request) |
367 | 367 | self.assertContains(response, 'Parent object') |
368 | 368 | |
… |
… |
class ChangeListTests(TestCase):
|
402 | 402 | for i in range(1, 10): |
403 | 403 | Child.objects.create(id=i, name='child %s' % i, parent=parent, age=i) |
404 | 404 | |
405 | | superuser = User.objects.create( |
406 | | username='superuser', |
407 | | is_superuser=True) |
408 | | |
409 | | def _mocked_authenticated_request(user): |
410 | | request = self.factory.get('/child/') |
411 | | request.user = user |
412 | | return request |
413 | | |
414 | 405 | m = DynamicListDisplayLinksChildAdmin(Child, admin.site) |
415 | | request = _mocked_authenticated_request(superuser) |
| 406 | superuser = self._create_superuser('superuser') |
| 407 | request = self._mocked_authenticated_request('/child/', superuser) |
416 | 408 | response = m.changelist_view(request) |
417 | 409 | for i in range(1, 10): |
418 | 410 | self.assertContains(response, '<a href="%s/">%s</a>' % (i, i)) |
… |
… |
class ChangeListTests(TestCase):
|
420 | 412 | list_display = m.get_list_display(request) |
421 | 413 | list_display_links = m.get_list_display_links(request, list_display) |
422 | 414 | self.assertEqual(list_display, ('parent', 'name', 'age')) |
423 | | self.assertEqual(list_display_links, ['age']) |
424 | | No newline at end of file |
| 415 | self.assertEqual(list_display_links, ['age']) |
| 416 | |
| 417 | def test_tuple_list_display(self): |
| 418 | """ |
| 419 | Regression test for #17128 |
| 420 | (ChangeList failing under Python 2.5 after r16319) |
| 421 | """ |
| 422 | swallow = Swallow.objects.create( |
| 423 | origin='Africa', load='12.34', speed='22.2') |
| 424 | model_admin = SwallowAdmin(Swallow, admin.site) |
| 425 | superuser = self._create_superuser('superuser') |
| 426 | request = self._mocked_authenticated_request('/swallow/', superuser) |
| 427 | response = model_admin.changelist_view(request) |
| 428 | # just want to ensure it doesn't blow up during rendering |
| 429 | self.assertContains(response, unicode(swallow.origin)) |
| 430 | self.assertContains(response, unicode(swallow.load)) |
| 431 | self.assertContains(response, unicode(swallow.speed)) |
| 432 | |