diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 6120182c87..b151cf2626 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -731,9 +731,16 @@ class ModelAdmin(BaseModelAdmin): Determines the HttpResponse for the change_view stage. """ opts = obj._meta + + # Handle proxy models automatically created by .only() or .defer() + verbose_name = opts.verbose_name + if obj._deferred: + opts_ = opts.proxy_for_model._meta + verbose_name = opts_.verbose_name + pk_value = obj._get_pk_val() - msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)} + msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(verbose_name), 'obj': force_unicode(obj)} if request.POST.has_key("_continue"): self.message_user(request, msg + ' ' + _("You may edit it again below.")) if request.REQUEST.has_key('_popup'): @@ -741,11 +748,11 @@ class ModelAdmin(BaseModelAdmin): else: return HttpResponseRedirect(request.path) elif request.POST.has_key("_saveasnew"): - msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': obj} + msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(verbose_name), 'obj': obj} self.message_user(request, msg) return HttpResponseRedirect("../%s/" % pk_value) elif request.POST.has_key("_addanother"): - self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) + self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(verbose_name))) return HttpResponseRedirect("../add/") else: self.message_user(request, msg) diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index 17d3dffe4d..374d3b7b0f 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -667,6 +667,37 @@ class FoodDeliveryAdmin(admin.ModelAdmin): list_display=('reference', 'driver', 'restaurant') list_editable = ('driver', 'restaurant') +class Paper(models.Model): + title = models.CharField(max_length=30) + author = models.CharField(max_length=30, blank=True, null=True) + +class CoverLetter(models.Model): + author = models.CharField(max_length=30) + date = models.DateField(null=True, blank=True) + + def __unicode__(self): + return self.author + +class PaperAdmin(admin.ModelAdmin): + """ + A ModelAdin with a custom queryset() method that uses only(), to test + verbose_name display in messages shown after adding Paper instances. + """ + + def queryset(self, request): + return super(PaperAdmin, self).queryset(request).only('title') + +class CoverLetterAdmin(admin.ModelAdmin): + """ + A ModelAdin 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. + """ + + def queryset(self, request): + #return super(CoverLetterAdmin, self).queryset(request).only('author') + return super(CoverLetterAdmin, self).queryset(request).defer('date') + admin.site.register(Article, ArticleAdmin) admin.site.register(CustomArticle, CustomArticleAdmin) @@ -706,6 +737,8 @@ admin.site.register(WorkHour, WorkHourAdmin) admin.site.register(Reservation) admin.site.register(FoodDelivery, FoodDeliveryAdmin) admin.site.register(RowLevelChangePermissionModel, RowLevelChangePermissionModelAdmin) +admin.site.register(Paper, PaperAdmin) +admin.site.register(CoverLetter, CoverLetterAdmin) # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. # That way we cover all four cases: diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index be6c6bb05e..bb91c40899 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -31,7 +31,7 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel, Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, Category, Post, Plot, FunkyTag, WorkHour, Employee, Inquisition, - Actor, FoodDelivery, RowLevelChangePermissionModel) + Actor, FoodDelivery, RowLevelChangePermissionModel, Paper, CoverLetter) class AdminViewBasicTest(TestCase): @@ -1840,6 +1840,37 @@ 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=u"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) + post_data = { + "title": u"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) + # Message should contain non-ugly model name. Instance representation is set by unicode() (ugly) + self.assertContains(response, '
  • The paper "Paper_Deferred_author object" was changed successfully.
  • ') + + # defer() is used in ModelAdmin.queryset() + cl = CoverLetter.objects.create(author=u"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) + post_data = { + "author": u"John Doe II", + "_save": "Save", + } + 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.
  • ') + class AdminInlineFileUploadTest(TestCase): fixtures = ['admin-views-users.xml', 'admin-views-actions.xml'] urlbit = 'admin' @@ -2626,4 +2657,4 @@ class DateHierarchyTests(TestCase): response = self.client.get(url) self.assert_non_localized_year(response, 2000) self.assert_non_localized_year(response, 2003) - self.assert_non_localized_year(response, 2005) \ No newline at end of file + self.assert_non_localized_year(response, 2005)