tests.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. from __future__ import unicode_literals
  2. from django.contrib import admin
  3. from django.contrib.admin.options import ModelAdmin
  4. from django.contrib.auth.models import User
  5. from django.test import RequestFactory, TestCase
  6. from .models import (
  7. Band, DynOrderingBandAdmin, Song, SongInlineDefaultOrdering,
  8. SongInlineNewOrdering,
  9. )
  10. class MockRequest(object):
  11. pass
  12. class MockSuperUser(object):
  13. def has_perm(self, perm):
  14. return True
  15. def has_module_perms(self, module):
  16. return True
  17. request = MockRequest()
  18. request.user = MockSuperUser()
  19. site = admin.AdminSite()
  20. class TestAdminOrdering(TestCase):
  21. """
  22. Let's make sure that ModelAdmin.get_queryset uses the ordering we define
  23. in ModelAdmin rather that ordering defined in the model's inner Meta
  24. class.
  25. """
  26. def setUp(self):
  27. self.request_factory = RequestFactory()
  28. Band.objects.bulk_create([
  29. Band(name='Aerosmith', bio='', rank=3),
  30. Band(name='Radiohead', bio='', rank=1),
  31. Band(name='Van Halen', bio='', rank=2),
  32. ])
  33. def test_default_ordering(self):
  34. """
  35. The default ordering should be by name, as specified in the inner Meta
  36. class.
  37. """
  38. ma = ModelAdmin(Band, site)
  39. names = [b.name for b in ma.get_queryset(request)]
  40. self.assertListEqual(['Aerosmith', 'Radiohead', 'Van Halen'], names)
  41. def test_specified_ordering(self):
  42. """
  43. Let's use a custom ModelAdmin that changes the ordering, and make sure
  44. it actually changes.
  45. """
  46. class BandAdmin(ModelAdmin):
  47. ordering = ('rank',) # default ordering is ('name',)
  48. ma = BandAdmin(Band, site)
  49. names = [b.name for b in ma.get_queryset(request)]
  50. self.assertListEqual(['Radiohead', 'Van Halen', 'Aerosmith'], names)
  51. def test_dynamic_ordering(self):
  52. """
  53. Let's use a custom ModelAdmin that changes the ordering dynamically.
  54. """
  55. super_user = User.objects.create(username='admin', is_superuser=True)
  56. other_user = User.objects.create(username='other')
  57. request = self.request_factory.get('/')
  58. request.user = super_user
  59. ma = DynOrderingBandAdmin(Band, site)
  60. names = [b.name for b in ma.get_queryset(request)]
  61. self.assertListEqual(['Radiohead', 'Van Halen', 'Aerosmith'], names)
  62. request.user = other_user
  63. names = [b.name for b in ma.get_queryset(request)]
  64. self.assertListEqual(['Aerosmith', 'Radiohead', 'Van Halen'], names)
  65. class TestInlineModelAdminOrdering(TestCase):
  66. """
  67. Let's make sure that InlineModelAdmin.get_queryset uses the ordering we
  68. define in InlineModelAdmin.
  69. """
  70. def setUp(self):
  71. self.band = Band.objects.create(name='Aerosmith', bio='', rank=3)
  72. Song.objects.bulk_create([
  73. Song(band=self.band, name='Pink', duration=235),
  74. Song(band=self.band, name='Dude (Looks Like a Lady)', duration=264),
  75. Song(band=self.band, name='Jaded', duration=214),
  76. ])
  77. def test_default_ordering(self):
  78. """
  79. The default ordering should be by name, as specified in the inner Meta
  80. class.
  81. """
  82. inline = SongInlineDefaultOrdering(self.band, site)
  83. names = [s.name for s in inline.get_queryset(request)]
  84. self.assertListEqual(['Dude (Looks Like a Lady)', 'Jaded', 'Pink'], names)
  85. def test_specified_ordering(self):
  86. """
  87. Let's check with ordering set to something different than the default.
  88. """
  89. inline = SongInlineNewOrdering(self.band, site)
  90. names = [s.name for s in inline.get_queryset(request)]
  91. self.assertListEqual(['Jaded', 'Pink', 'Dude (Looks Like a Lady)'], names)
  92. class TestRelatedFieldsAdminOrdering(TestCase):
  93. def setUp(self):
  94. self.b1 = Band.objects.create(name='Pink Floyd', bio='', rank=1)
  95. self.b2 = Band.objects.create(name='Foo Fighters', bio='', rank=5)
  96. # we need to register a custom ModelAdmin (instead of just using
  97. # ModelAdmin) because the field creator tries to find the ModelAdmin
  98. # for the related model
  99. class SongAdmin(admin.ModelAdmin):
  100. pass
  101. site.register(Song, SongAdmin)
  102. def tearDown(self):
  103. site.unregister(Song)
  104. if Band in site._registry:
  105. site.unregister(Band)
  106. def check_ordering_of_field_choices(self, correct_ordering):
  107. fk_field = site._registry[Song].formfield_for_foreignkey(Song.band.field, request=None)
  108. m2m_field = site._registry[Song].formfield_for_manytomany(Song.other_interpreters.field, request=None)
  109. self.assertListEqual(list(fk_field.queryset), correct_ordering)
  110. self.assertListEqual(list(m2m_field.queryset), correct_ordering)
  111. def test_no_admin_fallback_to_model_ordering(self):
  112. # should be ordered by name (as defined by the model)
  113. self.check_ordering_of_field_choices([self.b2, self.b1])
  114. def test_admin_with_no_ordering_fallback_to_model_ordering(self):
  115. class NoOrderingBandAdmin(admin.ModelAdmin):
  116. pass
  117. site.register(Band, NoOrderingBandAdmin)
  118. # should be ordered by name (as defined by the model)
  119. self.check_ordering_of_field_choices([self.b2, self.b1])
  120. def test_admin_ordering_beats_model_ordering(self):
  121. class StaticOrderingBandAdmin(admin.ModelAdmin):
  122. ordering = ('rank',)
  123. site.register(Band, StaticOrderingBandAdmin)
  124. # should be ordered by rank (defined by the ModelAdmin)
  125. self.check_ordering_of_field_choices([self.b1, self.b2])
  126. def test_custom_queryset_still_wins(self):
  127. """Test that custom queryset has still precedence (#21405)"""
  128. class SongAdmin(admin.ModelAdmin):
  129. # Exclude one of the two Bands from the querysets
  130. def formfield_for_foreignkey(self, db_field, request, **kwargs):
  131. if db_field.name == 'band':
  132. kwargs["queryset"] = Band.objects.filter(rank__gt=2)
  133. return super(SongAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
  134. def formfield_for_manytomany(self, db_field, request, **kwargs):
  135. if db_field.name == 'other_interpreters':
  136. kwargs["queryset"] = Band.objects.filter(rank__gt=2)
  137. return super(SongAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
  138. class StaticOrderingBandAdmin(admin.ModelAdmin):
  139. ordering = ('rank',)
  140. site.unregister(Song)
  141. site.register(Song, SongAdmin)
  142. site.register(Band, StaticOrderingBandAdmin)
  143. self.check_ordering_of_field_choices([self.b2])