diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 42c1516691..77c7705a10 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -748,9 +748,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 "_continue" in request.POST: self.message_user(request, msg + ' ' + _("You may edit it again below.")) if "_popup" in request.REQUEST: @@ -758,11 +765,11 @@ class ModelAdmin(BaseModelAdmin): else: return HttpResponseRedirect(request.path) elif "_saveasnew" in request.POST: - 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 "_addanother" in request.POST: - 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 7d6cab3cbf..9ac99cc9ef 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -704,6 +704,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) @@ -743,6 +774,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 642186eee2..bbef907aac 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -36,7 +36,7 @@ from models import (Article, BarAccount, CustomArticle, EmptyModel, Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, Category, Post, Plot, FunkyTag, Chapter, Book, Promo, WorkHour, Employee, Question, Answer, Inquisition, Actor, FoodDelivery, - RowLevelChangePermissionModel) + RowLevelChangePermissionModel, Paper, CoverLetter) class AdminViewBasicTest(TestCase): @@ -2029,6 +2029,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, '