tests.py 6.5 KB

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