diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index e9f4a43185..ce10cf72ba 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -24,7 +24,7 @@ from django.db.models.constants import LOOKUP_SEP from django.db.models.related import RelatedObject from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist from django.db.models.sql.constants import QUERY_TERMS -from django.http import Http404, HttpResponse, HttpResponseRedirect +from django.http import Http404, HttpResponseRedirect from django.http.response import HttpResponseBase from django.shortcuts import get_object_or_404 from django.template.response import SimpleTemplateResponse, TemplateResponse @@ -911,11 +911,10 @@ class ModelAdmin(BaseModelAdmin): # Here, we distinguish between different save types by checking for # the presence of keys in request.POST. if IS_POPUP_VAR in request.POST: - return HttpResponse( - '' - '' % \ - # escape() calls force_text. - (escape(pk_value), escapejs(obj))) + return SimpleTemplateResponse('admin/popup_response.html', { + 'pk_value': escape(pk_value), + 'obj': escapejs(obj) + }) elif "_continue" in request.POST: msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % msg_dict diff --git a/django/contrib/admin/templates/admin/popup_response.html b/django/contrib/admin/templates/admin/popup_response.html new file mode 100644 index 0000000000..44833b2f93 --- /dev/null +++ b/django/contrib/admin/templates/admin/popup_response.html @@ -0,0 +1,9 @@ + + + + + + + diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py index 5cc6f6251a..5ec4fbb544 100644 --- a/tests/admin_views/models.py +++ b/tests/admin_views/models.py @@ -137,7 +137,7 @@ class Thing(models.Model): class Actor(models.Model): name = models.CharField(max_length=50) age = models.IntegerField() - title = models.CharField(max_length=50, null=True) + title = models.CharField(max_length=50, null=True, blank=True) def __str__(self): return self.name diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 528c728069..064979801e 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -2554,6 +2554,17 @@ action) '/test_admin/admin/admin_views/subscriber/?%s' % IS_POPUP_VAR) self.assertEqual(response.context["action_form"], None) + def test_popup_template_response(self): + """ + Success on popups shall be rendered from template in order to allow + easy customization. + """ + response = self.client.post( + '/test_admin/admin/admin_views/actor/add/?%s=1' % IS_POPUP_VAR, + {'name': 'Troy McClure', 'age': '55', IS_POPUP_VAR: '1'}) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.template_name, 'admin/popup_response.html') + @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) class TestCustomChangeList(TestCase): @@ -4275,7 +4286,7 @@ class AdminKeepChangeListFiltersTests(TestCase): # Get the `add_view`. response = self.client.get(self.get_add_url()) self.assertEqual(response.status_code, 200) - + # Check the form action. form_action = """
""" % self.get_preserved_filters_querystring() self.assertContains(response, form_action, count=1)