Refs #27728 -- Made cosmetic edits to admin template tag template overriding.

This commit is contained in:
Tim Graham 2018-02-28 06:55:52 -05:00
parent fa352626c2
commit 4c02e3cda3
6 changed files with 43 additions and 48 deletions

View File

@ -475,17 +475,11 @@ def admin_actions_tag(parser, token):
return InclusionAdminNode(parser, token, func=admin_actions, template_name='actions.html')
def change_list_object_tools(context):
"""
Displays the row of change list object tools.
"""
return context
@register.tag(name='change_list_object_tools')
def change_list_object_tools_tag(parser, token):
"""Display the row of change list object tools."""
return InclusionAdminNode(
parser, token,
func=change_list_object_tools,
func=lambda context: context,
template_name='change_list_object_tools.html',
)

View File

@ -76,18 +76,12 @@ def submit_row_tag(parser, token):
return InclusionAdminNode(parser, token, func=submit_row, template_name='submit_line.html')
def change_form_object_tools(context):
"""
Displays the row of change form object tools.
"""
return context
@register.tag(name='change_form_object_tools')
def change_form_object_tools_tag(parser, token):
"""Display the row of change form object tools."""
return InclusionAdminNode(
parser, token,
func=change_form_object_tools,
func=lambda context: context,
template_name='change_form_object_tools.html',
)

View File

@ -4,19 +4,20 @@ from django.template.library import InclusionNode, parse_bits
class InclusionAdminNode(InclusionNode):
"""
Template tag that allows its template to be overridden per model, per app,
or globally.
"""
def __init__(self, parser, token, func, template_name, takes_context=True):
self.template_name = template_name
params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(func)
if len(params) > 0 and params[0] == 'self':
params = params[1:] # ignore 'self'
bits = token.split_contents()
args, kwargs = parse_bits(
parser, bits[1:], params, varargs, varkw, defaults, kwonly, kwonly_defaults, takes_context, bits[0]
)
super().__init__(
func=func, takes_context=takes_context, args=args, kwargs=kwargs, filename=None
parser, bits[1:], params, varargs, varkw, defaults, kwonly,
kwonly_defaults, takes_context, bits[0],
)
super().__init__(func, takes_context, args, kwargs, filename=None)
def render(self, context):
opts = context['opts']

View File

@ -2674,6 +2674,8 @@ And that's it! If we placed this file in the ``templates/admin/my_app``
directory, our link would appear on the change form for all models within
my_app.
.. _admin-templates-overridden-per-app-or-model:
Templates which may be overridden per app or model
--------------------------------------------------
@ -2701,7 +2703,7 @@ app or per model. The following can:
The ability to override the ``actions.html``, ``change_form_object_tools.html``,
``change_list_object_tools.html``, ``change_list_results.html``,
``date_hierarchy.html``, ``pagination.html``, ``prepopulated_fields_js.html``,
``search_form.html``, ``submit_line.html`` templates were added.
``search_form.html``, and ``submit_line.html`` templates 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

View File

@ -52,13 +52,16 @@ Minor features
* The new :meth:`.ModelAdmin.get_deleted_objects()` method allows customizing
the deletion process of the delete view and the "delete selected" action.
* The ``actions.html``, ``change_list_results.html``, ``date_hierarchy.html``,
``pagination.html``, ``prepopulated_fields_js.html``, ``search_form.html``
and ``submit_line.html`` templates can be overridden even per app or
per model, other than globally.
* The admin change list and change form object tools can now be overridden per app,
per model or globally with ``change_list_object_tools.html`` and
* The ``actions.html``, ``change_list_results.html``, ``date_hierarchy.html``,
``pagination.html``, ``prepopulated_fields_js.html``, ``search_form.html``,
and ``submit_line.html`` templates can now be :ref:`overridden per app or
per model <admin-templates-overridden-per-app-or-model>` (besides overridden
globally).
* The admin change list and change form object tools can now be :ref:`overridden
per app, per model, or globally <admin-templates-overridden-per-app-or-model>`
with ``change_list_object_tools.html`` and
``change_form_object_tools.html`` templates.
:mod:`django.contrib.admindocs`

View File

@ -7,7 +7,6 @@ from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.test import RequestFactory, TestCase
from django.urls import reverse
from django.utils.encoding import force_text
from .admin import ArticleAdmin, site
from .models import Article, Question
@ -29,9 +28,10 @@ class AdminTemplateTagsTest(AdminViewBasicTestCase):
self.assertIs(template_context['extra'], True)
self.assertIs(template_context['show_save'], True)
def test_can_override_change_form_templatetags(self):
def test_override_change_form_template_tags(self):
"""
admin_modify templatetags can follow the 'standard' search patter admin/app_label/model/template.html
admin_modify template tags follow the standard search pattern
admin/app_label/model/template.html.
"""
factory = RequestFactory()
article = Article.objects.all()[0]
@ -43,31 +43,32 @@ class AdminTemplateTagsTest(AdminViewBasicTestCase):
response.render()
self.assertIs(response.context_data['show_publish'], True)
self.assertIs(response.context_data['extra'], True)
content = force_text(response.content)
self.assertIs('name="_save"' in content, True)
self.assertIs('name="_publish"' in content, True)
self.assertIs('override-change_form_object_tools' in content, True)
self.assertIs('override-prepopulated_fields_js' in content, True)
content = str(response.content)
self.assertIn('name="_save"', content)
self.assertIn('name="_publish"', content)
self.assertIn('override-change_form_object_tools', content)
self.assertIn('override-prepopulated_fields_js', content)
def test_can_override_change_list_templatetags(self):
def test_override_change_list_template_tags(self):
"""
admin_list templatetags can follow the 'standard' search patter admin/app_label/model/template.html
admin_list template tags follow the standard search pattern
admin/app_label/model/template.html.
"""
factory = RequestFactory()
request = factory.get(reverse('admin:admin_views_article_changelist'))
request.user = self.superuser
admin = ArticleAdmin(Article, site)
admin.date_hierarchy = 'date'
admin.search_fields = ('title', 'content',)
admin.search_fields = ('title', 'content')
response = admin.changelist_view(request)
response.render()
content = force_text(response.content)
self.assertIs('override-actions' in content, True)
self.assertIs('override-change_list_object_tools' in content, True)
self.assertIs('override-change_list_results' in content, True)
self.assertIs('override-date_hierarchy' in content, True)
self.assertIs('override-pagination' in content, True)
self.assertIs('override-search_form' in content, True)
content = str(response.content)
self.assertIn('override-actions', content)
self.assertIn('override-change_list_object_tools', content)
self.assertIn('override-change_list_results', content)
self.assertIn('override-date_hierarchy', content)
self.assertIn('override-pagination', content)
self.assertIn('override-search_form', content)
class DateHierarchyTests(TestCase):