diff --git a/tests/regressiontests/admin_views/admin.py b/tests/regressiontests/admin_views/admin.py index 1e4e9b5c75..435883e637 100644 --- a/tests/regressiontests/admin_views/admin.py +++ b/tests/regressiontests/admin_views/admin.py @@ -27,7 +27,8 @@ from .models import (Article, Chapter, Account, Media, Child, Parent, Picture, Album, Question, Answer, ComplexSortedPerson, PrePopulatedPostLargeSlug, AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable, Report, Color2, UnorderedObject, MainPrepopulated, - RelatedPrepopulated, UndeletableObject, UserMessenger, Simple, Choice) + RelatedPrepopulated, UndeletableObject, UserMessenger, Simple, Choice, + ShortMessage, Telegram) def callable_year(dt_value): @@ -439,25 +440,54 @@ class FoodDeliveryAdmin(admin.ModelAdmin): list_editable = ('driver', 'restaurant') +class CoverLetterAdmin(admin.ModelAdmin): + """ + A ModelAdmin with a custom queryset() method that uses defer(), to test + verbose_name display in messages shown after adding/editing CoverLetter + instances. + Note that the CoverLetter model defines a __unicode__ method. + For testing fix for ticket #14529. + """ + + def queryset(self, request): + return super(CoverLetterAdmin, self).queryset(request).defer('date_written') + + class PaperAdmin(admin.ModelAdmin): """ A ModelAdmin with a custom queryset() method that uses only(), to test - verbose_name display in messages shown after adding Paper instances. + verbose_name display in messages shown after adding/editing Paper + instances. + For testing fix for ticket #14529. """ def queryset(self, request): return super(PaperAdmin, self).queryset(request).only('title') -class CoverLetterAdmin(admin.ModelAdmin): +class ShortMessageAdmin(admin.ModelAdmin): """ - A ModelAdmin with a custom queryset() method that uses only(), to test - verbose_name display in messages shown after adding CoverLetter instances. - Note that the CoverLetter model defines a __unicode__ method. + A ModelAdmin with a custom queryset() method that uses defer(), to test + verbose_name display in messages shown after adding/editing ShortMessage + instances. + For testing fix for ticket #14529. """ def queryset(self, request): - return super(CoverLetterAdmin, self).queryset(request).defer('date_written') + return super(ShortMessageAdmin, self).queryset(request).defer('timestamp') + + +class TelegramAdmin(admin.ModelAdmin): + """ + A ModelAdmin with a custom queryset() method that uses only(), to test + verbose_name display in messages shown after adding/editing Telegram + instances. + Note that the Telegram model defines a __unicode__ method. + For testing fix for ticket #14529. + """ + + def queryset(self, request): + return super(TelegramAdmin, self).queryset(request).only('title') class StoryForm(forms.ModelForm): @@ -665,6 +695,8 @@ site.register(FoodDelivery, FoodDeliveryAdmin) site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin) site.register(Paper, PaperAdmin) site.register(CoverLetter, CoverLetterAdmin) +site.register(ShortMessage, ShortMessageAdmin) +site.register(Telegram, TelegramAdmin) site.register(Story, StoryAdmin) site.register(OtherStory, OtherStoryAdmin) site.register(Report, ReportAdmin) diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index c641cfc0e6..5e25f0d542 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -548,11 +548,6 @@ class FoodDelivery(models.Model): unique_together = (("driver", "restaurant"),) -class Paper(models.Model): - title = models.CharField(max_length=30) - author = models.CharField(max_length=30, blank=True, null=True) - - @python_2_unicode_compatible class CoverLetter(models.Model): author = models.CharField(max_length=30) @@ -562,6 +557,25 @@ class CoverLetter(models.Model): return self.author +class Paper(models.Model): + title = models.CharField(max_length=30) + author = models.CharField(max_length=30, blank=True, null=True) + + +class ShortMessage(models.Model): + content = models.CharField(max_length=140) + timestamp = models.DateTimeField(null=True, blank=True) + + +@python_2_unicode_compatible +class Telegram(models.Model): + title = models.CharField(max_length=30) + date_sent = models.DateField(null=True, blank=True) + + def __str__(self): + return self.title + + class Story(models.Model): title = models.CharField(max_length=100) content = models.TextField() diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index a091785530..1eddb4b743 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -47,7 +47,7 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount, OtherStory, ComplexSortedPerson, Parent, Child, AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable, Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject, - Simple, UndeletableObject, Choice) + Simple, UndeletableObject, Choice, ShortMessage, Telegram) ERROR_MESSAGE = "Please enter the correct username and password \ @@ -2505,27 +2505,93 @@ class AdminCustomQuerysetTest(TestCase): else: self.assertEqual(response.status_code, 404) - def test_add_model_modeladmin_only_qs(self): - # only() is used in ModelAdmin.queryset() - p = Paper.objects.create(title="My Paper Title") - self.assertEqual(Paper.objects.count(), 1) - response = self.client.get('/test_admin/admin/admin_views/paper/%s/' % p.pk) + def test_add_model_modeladmin_defer_qs(self): + # Test for #14529. defer() is used in ModelAdmin.queryset() + + # model has __unicode__ method + self.assertEqual(CoverLetter.objects.count(), 0) + # Emulate model instance creation via the admin + post_data = { + "author": "Candidate, Best", + "_save": "Save", + } + response = self.client.post('/test_admin/admin/admin_views/coverletter/add/', + post_data, follow=True) self.assertEqual(response.status_code, 200) + self.assertEqual(CoverLetter.objects.count(), 1) + # Message should contain non-ugly model verbose name + self.assertContains( + response, + '
  • The cover letter "Candidate, Best" was added successfully.
  • ', + html=True + ) + + # model has no __unicode__ method + self.assertEqual(ShortMessage.objects.count(), 0) + # Emulate model instance creation via the admin + post_data = { + "content": "What's this SMS thing?", + "_save": "Save", + } + response = self.client.post('/test_admin/admin/admin_views/shortmessage/add/', + post_data, follow=True) + self.assertEqual(response.status_code, 200) + self.assertEqual(ShortMessage.objects.count(), 1) + # Message should contain non-ugly model verbose name + self.assertContains( + response, + '
  • The short message "ShortMessage object" was added successfully.
  • ', + html=True + ) + + def test_add_model_modeladmin_only_qs(self): + # Test for #14529. only() is used in ModelAdmin.queryset() + + # model has __unicode__ method + self.assertEqual(Telegram.objects.count(), 0) + # Emulate model instance creation via the admin + post_data = { + "title": "Urgent telegram", + "_save": "Save", + } + response = self.client.post('/test_admin/admin/admin_views/telegram/add/', + post_data, follow=True) + self.assertEqual(response.status_code, 200) + self.assertEqual(Telegram.objects.count(), 1) + # Message should contain non-ugly model verbose name + self.assertContains( + response, + '
  • The telegram "Urgent telegram" was added successfully.
  • ', + html=True + ) + + # model has no __unicode__ method + self.assertEqual(Paper.objects.count(), 0) + # Emulate model instance creation via the admin post_data = { "title": "My Modified Paper Title", "_save": "Save", } - response = self.client.post('/test_admin/admin/admin_views/paper/%s/' % p.pk, + response = self.client.post('/test_admin/admin/admin_views/paper/add/', post_data, follow=True) self.assertEqual(response.status_code, 200) - # Message should contain non-ugly model name. Instance representation is set by six.text_type() (ugly) - self.assertContains(response, '
  • The paper "Paper_Deferred_author object" was changed successfully.
  • ', html=True) + self.assertEqual(Paper.objects.count(), 1) + # Message should contain non-ugly model verbose name + self.assertContains( + response, + '
  • The paper "Paper object" was added successfully.
  • ', + html=True + ) - # defer() is used in ModelAdmin.queryset() + def test_edit_model_modeladmin_defer_qs(self): + # Test for #14529. defer() is used in ModelAdmin.queryset() + + # model has __unicode__ method cl = CoverLetter.objects.create(author="John Doe") self.assertEqual(CoverLetter.objects.count(), 1) response = self.client.get('/test_admin/admin/admin_views/coverletter/%s/' % cl.pk) self.assertEqual(response.status_code, 200) + # Emulate model instance edit via the admin post_data = { "author": "John Doe II", "_save": "Save", @@ -2533,8 +2599,83 @@ class AdminCustomQuerysetTest(TestCase): response = self.client.post('/test_admin/admin/admin_views/coverletter/%s/' % cl.pk, post_data, follow=True) self.assertEqual(response.status_code, 200) - # Message should contain non-ugly model name. Instance representation is set by model's __unicode__() - self.assertContains(response, '
  • The cover letter "John Doe II" was changed successfully.
  • ', html=True) + self.assertEqual(CoverLetter.objects.count(), 1) + # Message should contain non-ugly model verbose name. Instance + # representation is set by model's __unicode__() + self.assertContains( + response, + '
  • The cover letter "John Doe II" was changed successfully.
  • ', + html=True + ) + + # model has no __unicode__ method + sm = ShortMessage.objects.create(content="This is expensive") + self.assertEqual(ShortMessage.objects.count(), 1) + response = self.client.get('/test_admin/admin/admin_views/shortmessage/%s/' % sm.pk) + self.assertEqual(response.status_code, 200) + # Emulate model instance edit via the admin + post_data = { + "content": "Too expensive", + "_save": "Save", + } + response = self.client.post('/test_admin/admin/admin_views/shortmessage/%s/' % sm.pk, + post_data, follow=True) + self.assertEqual(response.status_code, 200) + self.assertEqual(ShortMessage.objects.count(), 1) + # Message should contain non-ugly model verbose name. The ugly(!) + # instance representation is set by six.text_type() + self.assertContains( + response, + '
  • The short message "ShortMessage_Deferred_timestamp object" was changed successfully.
  • ', + html=True + ) + + def test_edit_model_modeladmin_only_qs(self): + # Test for #14529. only() is used in ModelAdmin.queryset() + + # model has __unicode__ method + t = Telegram.objects.create(title="Frist Telegram") + self.assertEqual(Telegram.objects.count(), 1) + response = self.client.get('/test_admin/admin/admin_views/telegram/%s/' % t.pk) + self.assertEqual(response.status_code, 200) + # Emulate model instance edit via the admin + post_data = { + "title": "Telegram without typo", + "_save": "Save", + } + response = self.client.post('/test_admin/admin/admin_views/telegram/%s/' % t.pk, + post_data, follow=True) + self.assertEqual(response.status_code, 200) + self.assertEqual(Telegram.objects.count(), 1) + # Message should contain non-ugly model verbose name. The instance + # representation is set by model's __unicode__() + self.assertContains( + response, + '
  • The telegram "Telegram without typo" was changed successfully.
  • ', + html=True + ) + + # model has no __unicode__ method + p = Paper.objects.create(title="My Paper Title") + self.assertEqual(Paper.objects.count(), 1) + response = self.client.get('/test_admin/admin/admin_views/paper/%s/' % p.pk) + self.assertEqual(response.status_code, 200) + # Emulate model instance edit via the admin + post_data = { + "title": "My Modified Paper Title", + "_save": "Save", + } + response = self.client.post('/test_admin/admin/admin_views/paper/%s/' % p.pk, + post_data, follow=True) + self.assertEqual(response.status_code, 200) + self.assertEqual(Paper.objects.count(), 1) + # Message should contain non-ugly model verbose name. The ugly(!) + # instance representation is set by six.text_type() + self.assertContains( + response, + '
  • The paper "Paper_Deferred_author object" was changed successfully.
  • ', + html=True + ) @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))