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):
delete_confirmation_template = None
delete_selected_confirmation_template = None
object_history_template = None
popup_response_template = None
# Actions
actions = []
......@@ -1073,7 +1074,11 @@ class ModelAdmin(BaseModelAdmin):
'value': six.text_type(value),
'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,
})
......@@ -1119,8 +1124,9 @@ class ModelAdmin(BaseModelAdmin):
"""
if IS_POPUP_VAR in request.POST:
opts = obj._meta
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.
value = request.resolver_match.args[0]
new_value = obj.serializable_value(attr)
......@@ -1130,7 +1136,11 @@ class ModelAdmin(BaseModelAdmin):
'obj': six.text_type(obj),
'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,
})
......@@ -1299,7 +1309,11 @@ class ModelAdmin(BaseModelAdmin):
'action': 'delete',
'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,
})
......
......@@ -1318,6 +1318,12 @@ templates used by the :class:`ModelAdmin` views:
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:
......@@ -2516,6 +2522,11 @@ app or per model. The following can:
* ``change_list.html``
* ``delete_confirmation.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
override them for your entire project. Just place the new version in your
......
......@@ -72,6 +72,10 @@ Minor features
<django.contrib.admin.ModelAdmin.get_exclude>` hook allows specifying the
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`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -162,6 +162,7 @@ class CustomArticleAdmin(admin.ModelAdmin):
object_history_template = 'custom_admin/object_history.html'
delete_confirmation_template = 'custom_admin/delete_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):
return super(CustomArticleAdmin, self).changelist_view(
......
......@@ -969,6 +969,16 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
response = self.client.get(reverse('admin:admin_views_customarticle_history', args=(article_pk,)))
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):
"""
The admin/change_form.html template uses block.super in the
......@@ -3433,7 +3443,7 @@ action)</option>
reverse('admin:admin_views_subscriber_changelist') + '?%s' % IS_POPUP_VAR)
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
easy customization.
......@@ -3442,7 +3452,40 @@ action)</option>
reverse('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')
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):
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