Kaydet (Commit) 1e629928 authored tarafından Michael Scott's avatar Michael Scott Kaydeden (comit) Tim Graham

Fixed #27313 -- Allowed overriding admin popup response template.

üst fb1349ce
...@@ -509,6 +509,7 @@ class ModelAdmin(BaseModelAdmin): ...@@ -509,6 +509,7 @@ class ModelAdmin(BaseModelAdmin):
delete_confirmation_template = None delete_confirmation_template = None
delete_selected_confirmation_template = None delete_selected_confirmation_template = None
object_history_template = None object_history_template = None
popup_response_template = None
# Actions # Actions
actions = [] actions = []
...@@ -1073,7 +1074,11 @@ class ModelAdmin(BaseModelAdmin): ...@@ -1073,7 +1074,11 @@ class ModelAdmin(BaseModelAdmin):
'value': six.text_type(value), 'value': six.text_type(value),
'obj': six.text_type(obj), 'obj': six.text_type(obj),
}) })
return SimpleTemplateResponse('admin/popup_response.html', { return TemplateResponse(request, self.popup_response_template or [
'admin/%s/%s/popup_response.html' % (opts.app_label, opts.model_name),
'admin/%s/popup_response.html' % opts.app_label,
'admin/popup_response.html',
], {
'popup_response_data': popup_response_data, 'popup_response_data': popup_response_data,
}) })
...@@ -1119,8 +1124,9 @@ class ModelAdmin(BaseModelAdmin): ...@@ -1119,8 +1124,9 @@ class ModelAdmin(BaseModelAdmin):
""" """
if IS_POPUP_VAR in request.POST: if IS_POPUP_VAR in request.POST:
opts = obj._meta
to_field = request.POST.get(TO_FIELD_VAR) to_field = request.POST.get(TO_FIELD_VAR)
attr = str(to_field) if to_field else obj._meta.pk.attname attr = str(to_field) if to_field else opts.pk.attname
# Retrieve the `object_id` from the resolved pattern arguments. # Retrieve the `object_id` from the resolved pattern arguments.
value = request.resolver_match.args[0] value = request.resolver_match.args[0]
new_value = obj.serializable_value(attr) new_value = obj.serializable_value(attr)
...@@ -1130,7 +1136,11 @@ class ModelAdmin(BaseModelAdmin): ...@@ -1130,7 +1136,11 @@ class ModelAdmin(BaseModelAdmin):
'obj': six.text_type(obj), 'obj': six.text_type(obj),
'new_value': six.text_type(new_value), 'new_value': six.text_type(new_value),
}) })
return SimpleTemplateResponse('admin/popup_response.html', { return TemplateResponse(request, self.popup_response_template or [
'admin/%s/%s/popup_response.html' % (opts.app_label, opts.model_name),
'admin/%s/popup_response.html' % opts.app_label,
'admin/popup_response.html',
], {
'popup_response_data': popup_response_data, 'popup_response_data': popup_response_data,
}) })
...@@ -1299,7 +1309,11 @@ class ModelAdmin(BaseModelAdmin): ...@@ -1299,7 +1309,11 @@ class ModelAdmin(BaseModelAdmin):
'action': 'delete', 'action': 'delete',
'value': str(obj_id), 'value': str(obj_id),
}) })
return SimpleTemplateResponse('admin/popup_response.html', { return TemplateResponse(request, self.popup_response_template or [
'admin/%s/%s/popup_response.html' % (opts.app_label, opts.model_name),
'admin/%s/popup_response.html' % opts.app_label,
'admin/popup_response.html',
], {
'popup_response_data': popup_response_data, 'popup_response_data': popup_response_data,
}) })
......
...@@ -1318,6 +1318,12 @@ templates used by the :class:`ModelAdmin` views: ...@@ -1318,6 +1318,12 @@ templates used by the :class:`ModelAdmin` views:
Path to a custom template, used by :meth:`history_view`. Path to a custom template, used by :meth:`history_view`.
.. attribute:: ModelAdmin.popup_response_template
.. versionadded:: 1.11
Path to a custom template, used by :meth:`response_add`,
:meth:`response_change`, and :meth:`response_delete`.
.. _model-admin-methods: .. _model-admin-methods:
...@@ -2516,6 +2522,11 @@ app or per model. The following can: ...@@ -2516,6 +2522,11 @@ app or per model. The following can:
* ``change_list.html`` * ``change_list.html``
* ``delete_confirmation.html`` * ``delete_confirmation.html``
* ``object_history.html`` * ``object_history.html``
* ``popup_response.html``
.. versionchanged:: 1.11
The ability to override the ``popup_response.html`` template was added.
For those templates that cannot be overridden in this way, you may still For those templates that cannot be overridden in this way, you may still
override them for your entire project. Just place the new version in your override them for your entire project. Just place the new version in your
......
...@@ -72,6 +72,10 @@ Minor features ...@@ -72,6 +72,10 @@ Minor features
<django.contrib.admin.ModelAdmin.get_exclude>` hook allows specifying the <django.contrib.admin.ModelAdmin.get_exclude>` hook allows specifying the
exclude fields based on the request or model instance. exclude fields based on the request or model instance.
* The ``popup_response.html`` template can now be overridden per app, per
model, or by setting the :attr:`.ModelAdmin.popup_response_template`
attribute.
:mod:`django.contrib.admindocs` :mod:`django.contrib.admindocs`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -162,6 +162,7 @@ class CustomArticleAdmin(admin.ModelAdmin): ...@@ -162,6 +162,7 @@ class CustomArticleAdmin(admin.ModelAdmin):
object_history_template = 'custom_admin/object_history.html' object_history_template = 'custom_admin/object_history.html'
delete_confirmation_template = 'custom_admin/delete_confirmation.html' delete_confirmation_template = 'custom_admin/delete_confirmation.html'
delete_selected_confirmation_template = 'custom_admin/delete_selected_confirmation.html' delete_selected_confirmation_template = 'custom_admin/delete_selected_confirmation.html'
popup_response_template = 'custom_admin/popup_response.html'
def changelist_view(self, request): def changelist_view(self, request):
return super(CustomArticleAdmin, self).changelist_view( return super(CustomArticleAdmin, self).changelist_view(
......
...@@ -969,6 +969,16 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase): ...@@ -969,6 +969,16 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
response = self.client.get(reverse('admin:admin_views_customarticle_history', args=(article_pk,))) response = self.client.get(reverse('admin:admin_views_customarticle_history', args=(article_pk,)))
self.assertTemplateUsed(response, 'custom_admin/object_history.html') self.assertTemplateUsed(response, 'custom_admin/object_history.html')
# A custom popup response template may be specified by
# ModelAdmin.popup_response_template.
response = self.client.post(reverse('admin:admin_views_customarticle_add') + '?%s=1' % IS_POPUP_VAR, {
'content': '<p>great article</p>',
'date_0': '2008-03-18',
'date_1': '10:54:39',
IS_POPUP_VAR: '1'
})
self.assertEqual(response.template_name, 'custom_admin/popup_response.html')
def test_extended_bodyclass_template_change_form(self): def test_extended_bodyclass_template_change_form(self):
""" """
The admin/change_form.html template uses block.super in the The admin/change_form.html template uses block.super in the
...@@ -3433,7 +3443,7 @@ action)</option> ...@@ -3433,7 +3443,7 @@ action)</option>
reverse('admin:admin_views_subscriber_changelist') + '?%s' % IS_POPUP_VAR) reverse('admin:admin_views_subscriber_changelist') + '?%s' % IS_POPUP_VAR)
self.assertIsNone(response.context["action_form"]) self.assertIsNone(response.context["action_form"])
def test_popup_template_response(self): def test_popup_template_response_on_add(self):
""" """
Success on popups shall be rendered from template in order to allow Success on popups shall be rendered from template in order to allow
easy customization. easy customization.
...@@ -3442,7 +3452,40 @@ action)</option> ...@@ -3442,7 +3452,40 @@ action)</option>
reverse('admin:admin_views_actor_add') + '?%s=1' % IS_POPUP_VAR, reverse('admin:admin_views_actor_add') + '?%s=1' % IS_POPUP_VAR,
{'name': 'Troy McClure', 'age': '55', IS_POPUP_VAR: '1'}) {'name': 'Troy McClure', 'age': '55', IS_POPUP_VAR: '1'})
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name, 'admin/popup_response.html') self.assertListEqual(response.template_name, [
'admin/admin_views/actor/popup_response.html',
'admin/admin_views/popup_response.html',
'admin/popup_response.html',
])
self.assertTemplateUsed(response, 'admin/popup_response.html')
def test_popup_template_response_on_change(self):
instance = Actor.objects.create(name='David Tennant', age=45)
response = self.client.post(
reverse('admin:admin_views_actor_change', args=(instance.pk,)) + '?%s=1' % IS_POPUP_VAR,
{'name': 'David Tennant', 'age': '46', IS_POPUP_VAR: '1'}
)
self.assertEqual(response.status_code, 200)
self.assertListEqual(response.template_name, [
'admin/admin_views/actor/popup_response.html',
'admin/admin_views/popup_response.html',
'admin/popup_response.html',
])
self.assertTemplateUsed(response, 'admin/popup_response.html')
def test_popup_template_response_on_delete(self):
instance = Actor.objects.create(name='David Tennant', age=45)
response = self.client.post(
reverse('admin:admin_views_actor_delete', args=(instance.pk,)) + '?%s=1' % IS_POPUP_VAR,
{IS_POPUP_VAR: '1'}
)
self.assertEqual(response.status_code, 200)
self.assertListEqual(response.template_name, [
'admin/admin_views/actor/popup_response.html',
'admin/admin_views/popup_response.html',
'admin/popup_response.html',
])
self.assertTemplateUsed(response, 'admin/popup_response.html')
def test_popup_template_escaping(self): def test_popup_template_escaping(self):
popup_response_data = json.dumps({ popup_response_data = json.dumps({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment