Ticket #14206: 14206_r16337.diff
File 14206_r16337.diff, 11.5 KB (added by , 13 years ago) |
---|
-
docs/ref/contrib/admin/index.txt
967 967 a ``dictionary``, as described above in the :attr:`ModelAdmin.prepopulated_fields` 968 968 section. 969 969 970 .. method:: ModelAdmin.get_list_display(self, request) 971 972 .. versionadded:: 1.4 973 974 The ``get_list_display`` method is given the ``HttpRequest`` and is 975 expected to return a ``list`` or ``tuple`` of field names that will be 976 displayed on the changelist view as described above in the 977 :attr:`ModelAdmin.list_display` section. 978 970 979 .. method:: ModelAdmin.get_urls(self) 971 980 972 981 The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for -
django/contrib/admin/options.py
625 625 description = capfirst(action.replace('_', ' ')) 626 626 return func, action, description 627 627 628 def get_list_display(self, request): 629 """ 630 Return a sequence containing the fields to be displayed on the 631 changelist. 632 """ 633 return self.list_display 634 628 635 def construct_change_message(self, request, form, formsets): 629 636 """ 630 637 Construct a change message from a changed object. … … 1053 1060 actions = self.get_actions(request) 1054 1061 1055 1062 # Remove action checkboxes if there aren't any actions available. 1056 list_display = list(self. list_display)1063 list_display = list(self.get_list_display(request)) 1057 1064 if not actions: 1058 1065 try: 1059 1066 list_display.remove('action_checkbox') -
tests/regressiontests/admin_changelist/tests.py
4 4 from django.core.paginator import Paginator 5 5 from django.template import Context, Template 6 6 from django.test import TransactionTestCase 7 from django.test.client import RequestFactory 8 from django.contrib.auth.models import User 7 9 8 10 from models import (Child, Parent, Genre, Band, Musician, Group, Quartet, 9 11 Membership, ChordsMusician, ChordsBand, Invitation) 10 12 11 13 12 14 class ChangeListTests(TransactionTestCase): 15 def setUp(self): 16 self.factory = RequestFactory() 17 13 18 def test_select_related_preserved(self): 14 19 """ 15 20 Regression test for #10348: ChangeList.get_query_set() shouldn't 16 21 overwrite a custom select_related provided by ModelAdmin.queryset(). 17 22 """ 18 23 m = ChildAdmin(Child, admin.site) 19 cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links, 24 request = self.factory.get('/child/') 25 cl = ChangeList(request, Child, m.list_display, m.list_display_links, 20 26 m.list_filter, m.date_hierarchy, m.search_fields, 21 27 m.list_select_related, m.list_per_page, m.list_editable, m) 22 28 self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}}) … … 27 33 for relationship fields 28 34 """ 29 35 new_child = Child.objects.create(name='name', parent=None) 30 request = MockRequest()36 request = self.factory.get('/child/') 31 37 m = ChildAdmin(Child, admin.site) 32 38 cl = ChangeList(request, Child, m.list_display, m.list_display_links, 33 39 m.list_filter, m.date_hierarchy, m.search_fields, … … 40 46 self.assertFalse(table_output.find(row_html) == -1, 41 47 'Failed to find expected row element: %s' % table_output) 42 48 43 44 49 def test_result_list_html(self): 45 50 """ 46 51 Verifies that inclusion tag result_list generates a table when with … … 48 53 """ 49 54 new_parent = Parent.objects.create(name='parent') 50 55 new_child = Child.objects.create(name='name', parent=new_parent) 51 request = MockRequest()56 request = self.factory.get('/child/') 52 57 m = ChildAdmin(Child, admin.site) 53 58 cl = ChangeList(request, Child, m.list_display, m.list_display_links, 54 59 m.list_filter, m.date_hierarchy, m.search_fields, … … 72 77 """ 73 78 new_parent = Parent.objects.create(name='parent') 74 79 new_child = Child.objects.create(name='name', parent=new_parent) 75 request = MockRequest()80 request = self.factory.get('/child/') 76 81 m = ChildAdmin(Child, admin.site) 77 82 78 83 # Test with list_editable fields … … 104 109 new_parent = Parent.objects.create(name='parent') 105 110 for i in range(200): 106 111 new_child = Child.objects.create(name='name %s' % i, parent=new_parent) 107 request = MockRequest() 108 request.GET['p'] = -1 # Anything outside range 112 request = self.factory.get('/child/', data={'p': -1}) # Anything outside range 109 113 m = ChildAdmin(Child, admin.site) 110 114 111 115 # Test with list_editable fields … … 122 126 for i in range(200): 123 127 new_child = Child.objects.create(name='name %s' % i, parent=new_parent) 124 128 125 request = MockRequest()129 request = self.factory.get('/child/') 126 130 m = ChildAdmin(Child, admin.site) 127 131 m.list_display = ['id', 'name', 'parent'] 128 132 m.list_display_links = ['id'] … … 148 152 band.genres.add(blues) 149 153 150 154 m = BandAdmin(Band, admin.site) 151 request = MockFilterRequest('genres', blues.pk)155 request = self.factory.get('/band/', data={'genres': blues.pk}) 152 156 153 157 cl = ChangeList(request, Band, m.list_display, 154 158 m.list_display_links, m.list_filter, m.date_hierarchy, … … 171 175 Membership.objects.create(group=band, music=lead, role='bass player') 172 176 173 177 m = GroupAdmin(Group, admin.site) 174 request = MockFilterRequest('members', lead.pk)178 request = self.factory.get('/group/', data={'members': lead.pk}) 175 179 176 180 cl = ChangeList(request, Group, m.list_display, 177 181 m.list_display_links, m.list_filter, m.date_hierarchy, … … 195 199 Membership.objects.create(group=four, music=lead, role='guitar player') 196 200 197 201 m = QuartetAdmin(Quartet, admin.site) 198 request = MockFilterRequest('members', lead.pk)202 request = self.factory.get('/quartet/', data={'members': lead.pk}) 199 203 200 204 cl = ChangeList(request, Quartet, m.list_display, 201 205 m.list_display_links, m.list_filter, m.date_hierarchy, … … 219 223 Invitation.objects.create(band=three, player=lead, instrument='bass') 220 224 221 225 m = ChordsBandAdmin(ChordsBand, admin.site) 222 request = MockFilterRequest('members', lead.pk)226 request = self.factory.get('/chordsband/', data={'members': lead.pk}) 223 227 224 228 cl = ChangeList(request, ChordsBand, m.list_display, 225 229 m.list_display_links, m.list_filter, m.date_hierarchy, … … 242 246 Child.objects.create(parent=parent, name='Daniel') 243 247 244 248 m = ParentAdmin(Parent, admin.site) 245 request = MockFilterRequest('child__name', 'Daniel')249 request = self.factory.get('/parent/', data={'child__name': 'Daniel'}) 246 250 247 251 cl = ChangeList(request, Parent, m.list_display, m.list_display_links, 248 252 m.list_filter, m.date_hierarchy, m.search_fields, … … 262 266 Child.objects.create(parent=parent, name='Daniel') 263 267 264 268 m = ParentAdmin(Parent, admin.site) 265 request = MockSearchRequest('daniel')269 request = self.factory.get('/parent/', data={SEARCH_VAR: 'daniel'}) 266 270 267 271 cl = ChangeList(request, Parent, m.list_display, m.list_display_links, 268 272 m.list_filter, m.date_hierarchy, m.search_fields, … … 282 286 Child.objects.create(name='name %s' % i, parent=parent) 283 287 Child.objects.create(name='filtered %s' % i, parent=parent) 284 288 285 request = MockRequest()289 request = self.factory.get('/child/') 286 290 287 291 # Test default queryset 288 292 m = ChildAdmin(Child, admin.site) … … 302 306 self.assertEqual(cl.paginator.count, 30) 303 307 self.assertEqual(cl.paginator.page_range, [1, 2, 3]) 304 308 309 def test_dynamic_list_display(self): 310 """ 311 Regression tests for #14206: dynamic list_display support. 312 """ 313 parent = Parent.objects.create(name='parent') 314 for i in range(10): 315 Child.objects.create(name='child %s' % i, parent=parent) 305 316 317 user_noparents = User.objects.create( 318 username='noparents', 319 is_superuser=True) 320 user_parents = User.objects.create( 321 username='parents', 322 is_superuser=True) 323 324 def _mocked_authenticated_request(user): 325 request = self.factory.get('/child/') 326 request.user = user 327 return request 328 329 # Test with user 'noparents' 330 m = DynamicListDisplayChildAdmin(Child, admin.site) 331 request = _mocked_authenticated_request(user_noparents) 332 response = m.changelist_view(request) 333 # XXX - Calling render here to avoid ContentNotRenderedError to be 334 # raised. Ticket #15826 should fix this but it's not yet integrated. 335 response.render() 336 self.assertNotContains(response, 'Parent object') 337 338 # Test with user 'parents' 339 m = DynamicListDisplayChildAdmin(Child, admin.site) 340 request = _mocked_authenticated_request(user_parents) 341 response = m.changelist_view(request) 342 # XXX - #15826 343 response.render() 344 self.assertContains(response, 'Parent object') 345 346 # Test default implementation 347 m = ChildAdmin(Child, admin.site) 348 request = _mocked_authenticated_request(user_noparents) 349 response = m.changelist_view(request) 350 # XXX - #15826 351 response.render() 352 self.assertContains(response, 'Parent object') 353 354 306 355 class ParentAdmin(admin.ModelAdmin): 307 356 list_filter = ['child__name'] 308 357 search_fields = ['child__name'] … … 311 360 class ChildAdmin(admin.ModelAdmin): 312 361 list_display = ['name', 'parent'] 313 362 list_per_page = 10 363 314 364 def queryset(self, request): 315 365 return super(ChildAdmin, self).queryset(request).select_related("parent__name") 316 366 367 317 368 class FilteredChildAdmin(admin.ModelAdmin): 318 369 list_display = ['name', 'parent'] 319 370 list_per_page = 10 371 320 372 def queryset(self, request): 321 373 return super(FilteredChildAdmin, self).queryset(request).filter( 322 374 name__contains='filtered') 323 375 324 class MockRequest(object):325 GET = {}326 376 327 377 class CustomPaginator(Paginator): 328 378 def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True): … … 333 383 class BandAdmin(admin.ModelAdmin): 334 384 list_filter = ['genres'] 335 385 386 336 387 class GroupAdmin(admin.ModelAdmin): 337 388 list_filter = ['members'] 338 389 390 339 391 class QuartetAdmin(admin.ModelAdmin): 340 392 list_filter = ['members'] 341 393 394 342 395 class ChordsBandAdmin(admin.ModelAdmin): 343 396 list_filter = ['members'] 344 397 345 class MockFilterRequest(object):346 def __init__(self, filter, q):347 self.GET = {filter: q}348 398 349 class MockSearchRequest(object): 350 def __init__(self, q): 351 self.GET = {SEARCH_VAR: q} 399 class DynamicListDisplayChildAdmin(admin.ModelAdmin): 400 list_display = ('name', 'parent') 401 402 def get_list_display(self, request): 403 my_list_display = list(self.list_display) 404 if request.user.username == 'noparents': 405 my_list_display.remove('parent') 406 407 return my_list_display