diff --git a/django/contrib/admin/static/admin/css/base.css b/django/contrib/admin/static/admin/css/base.css index 4f4773284e..bdeefbc6e9 100644 --- a/django/contrib/admin/static/admin/css/base.css +++ b/django/contrib/admin/static/admin/css/base.css @@ -118,6 +118,15 @@ a:focus { text-decoration: underline; } +a:not( + [role="button"], + #header a, + #nav-sidebar a, + #content-main.app-list a +) { + text-decoration: underline; +} + a img { border: none; } diff --git a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js index aa1cae9eeb..8168172a97 100644 --- a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js +++ b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js @@ -108,6 +108,7 @@ const now_link = document.createElement('a'); now_link.href = "#"; now_link.textContent = gettext('Now'); + now_link.role = 'button'; now_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.handleClockQuicklink(num, -1); @@ -163,7 +164,7 @@ // where name is the name attribute of the . const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name; DateTimeShortcuts.clockHours[name].forEach(function(element) { - const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#'); + const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'role', 'button', 'href', '#'); time_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.handleClockQuicklink(num, element[1]); @@ -172,7 +173,7 @@ const cancel_p = quickElement('p', clock_box); cancel_p.className = 'calendar-cancel'; - const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#'); + const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'role', 'button', 'href', '#'); cancel_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.dismissClock(num); @@ -235,6 +236,7 @@ inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); const today_link = document.createElement('a'); today_link.href = '#'; + today_link.role = 'button'; today_link.appendChild(document.createTextNode(gettext('Today'))); today_link.addEventListener('click', function(e) { e.preventDefault(); @@ -309,19 +311,19 @@ // calendar shortcuts const shortcuts = quickElement('div', cal_box); shortcuts.className = 'calendar-shortcuts'; - let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#'); + let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'role', 'button', 'href', '#'); day_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.handleCalendarQuickLink(num, -1); }); shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - day_link = quickElement('a', shortcuts, gettext('Today'), 'href', '#'); + day_link = quickElement('a', shortcuts, gettext('Today'), 'role', 'button', 'href', '#'); day_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.handleCalendarQuickLink(num, 0); }); shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0')); - day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'href', '#'); + day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'role', 'button', 'href', '#'); day_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.handleCalendarQuickLink(num, +1); @@ -330,7 +332,7 @@ // cancel bar const cancel_p = quickElement('p', cal_box); cancel_p.className = 'calendar-cancel'; - const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#'); + const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'role', 'button', 'href', '#'); cancel_link.addEventListener('click', function(e) { e.preventDefault(); DateTimeShortcuts.dismissCalendar(num); diff --git a/django/contrib/admin/static/admin/js/calendar.js b/django/contrib/admin/static/admin/js/calendar.js index 776310f75b..b13242078a 100644 --- a/django/contrib/admin/static/admin/js/calendar.js +++ b/django/contrib/admin/static/admin/js/calendar.js @@ -160,7 +160,7 @@ depends on core.js for utility functions like removeChildren or quickElement } const cell = quickElement('td', tableRow, '', 'class', todayClass); - const link = quickElement('a', cell, currentDay, 'href', '#'); + const link = quickElement('a', cell, currentDay, 'role', 'button', 'href', '#'); link.addEventListener('click', calendarMonth(year, month)); currentDay++; } diff --git a/django/contrib/admin/templates/admin/change_form_object_tools.html b/django/contrib/admin/templates/admin/change_form_object_tools.html index 067ae83761..2ab2b541e7 100644 --- a/django/contrib/admin/templates/admin/change_form_object_tools.html +++ b/django/contrib/admin/templates/admin/change_form_object_tools.html @@ -2,7 +2,7 @@ {% block object-tools-items %}
  • {% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %} - {% translate "History" %} + {% translate "History" %}
  • {% if has_absolute_url %}
  • {% translate "View on site" %}
  • {% endif %} {% endblock %} diff --git a/django/contrib/admin/templates/admin/change_list_object_tools.html b/django/contrib/admin/templates/admin/change_list_object_tools.html index 11cc6fa4ba..35bff31fb7 100644 --- a/django/contrib/admin/templates/admin/change_list_object_tools.html +++ b/django/contrib/admin/templates/admin/change_list_object_tools.html @@ -4,7 +4,7 @@ {% if has_add_permission %}
  • {% url cl.opts|admin_urlname:'add' as add_url %} - + {% blocktranslate with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktranslate %}
  • diff --git a/django/contrib/admin/templates/admin/change_list_results.html b/django/contrib/admin/templates/admin/change_list_results.html index d2a9feed20..bea4a5b859 100644 --- a/django/contrib/admin/templates/admin/change_list_results.html +++ b/django/contrib/admin/templates/admin/change_list_results.html @@ -18,7 +18,7 @@ {% endif %} -
    {% if header.sortable %}{{ header.text|capfirst }}{% else %}{{ header.text|capfirst }}{% endif %}
    +
    {% if header.sortable %}{{ header.text|capfirst }}{% else %}{{ header.text|capfirst }}{% endif %}
    {% endfor %} diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html index e3f08ee651..2ccf719e05 100644 --- a/django/contrib/admin/templates/admin/delete_confirmation.html +++ b/django/contrib/admin/templates/admin/delete_confirmation.html @@ -42,7 +42,7 @@ {% if is_popup %}{% endif %} {% if to_field %}{% endif %} - {% translate "No, take me back" %} + {% translate "No, take me back" %} {% endblock %} diff --git a/django/contrib/admin/templates/admin/delete_selected_confirmation.html b/django/contrib/admin/templates/admin/delete_selected_confirmation.html index 51b93a5f49..2414e79095 100644 --- a/django/contrib/admin/templates/admin/delete_selected_confirmation.html +++ b/django/contrib/admin/templates/admin/delete_selected_confirmation.html @@ -40,7 +40,7 @@ - {% translate "No, take me back" %} + {% translate "No, take me back" %} {% endif %} diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html index 899727a4ba..502515a8f5 100644 --- a/django/contrib/admin/templates/admin/index.html +++ b/django/contrib/admin/templates/admin/index.html @@ -12,7 +12,7 @@ {% block nav-sidebar %}{% endblock %} {% block content %} -
    +
    {% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
    {% endblock %} diff --git a/django/contrib/admin/templates/admin/object_history.html b/django/contrib/admin/templates/admin/object_history.html index f83984c300..2b3b06caa0 100644 --- a/django/contrib/admin/templates/admin/object_history.html +++ b/django/contrib/admin/templates/admin/object_history.html @@ -42,7 +42,7 @@ {% elif i == action_list.number %} {{ i }} {% else %} - {{ i }} + {{ i }} {% endif %} {% endfor %} {% endif %} diff --git a/django/contrib/admin/templates/admin/submit_line.html b/django/contrib/admin/templates/admin/submit_line.html index b2b2054966..5390dd36c1 100644 --- a/django/contrib/admin/templates/admin/submit_line.html +++ b/django/contrib/admin/templates/admin/submit_line.html @@ -7,11 +7,11 @@ {% if show_save_and_continue %}{% endif %} {% if show_close %} {% url opts|admin_urlname:'changelist' as changelist_url %} - {% translate 'Close' %} + {% translate 'Close' %} {% endif %} {% if show_delete_link and original %} {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %} - {% translate "Delete" %} + {% translate "Delete" %} {% endif %} {% endblock %}
    diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index 6615e98bbf..e7cb244af1 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -45,7 +45,7 @@ def paginator_number(cl, i): return format_html('{} ', i) else: return format_html( - '{} ', + '{} ', cl.get_query_string({PAGE_VAR: i}), mark_safe(' class="end"' if i == cl.paginator.num_pages else ""), i, diff --git a/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html b/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html index e95fa3e9da..b48204b7eb 100644 --- a/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html +++ b/django/contrib/auth/templates/auth/widgets/read_only_password_hash.html @@ -4,5 +4,5 @@ {{ entry.label }}{% if entry.value %}: {{ entry.value }}{% endif %} {% endfor %}

    -

    {{ button_label }}

    +

    {{ button_label }}

    diff --git a/docs/intro/_images/admin04t.png b/docs/intro/_images/admin04t.png index 517b2296b3..2890ebf517 100644 Binary files a/docs/intro/_images/admin04t.png and b/docs/intro/_images/admin04t.png differ diff --git a/docs/intro/_images/admin12t.png b/docs/intro/_images/admin12t.png index 6b43c7ae6d..7dafa6614f 100644 Binary files a/docs/intro/_images/admin12t.png and b/docs/intro/_images/admin12t.png differ diff --git a/docs/intro/_images/admin13t.png b/docs/intro/_images/admin13t.png index 0d79edefd4..6ccba2636f 100644 Binary files a/docs/intro/_images/admin13t.png and b/docs/intro/_images/admin13t.png differ diff --git a/docs/ref/contrib/admin/_images/actions-as-modeladmin-methods.png b/docs/ref/contrib/admin/_images/actions-as-modeladmin-methods.png index 6ae454e0de..a0939a28a2 100644 Binary files a/docs/ref/contrib/admin/_images/actions-as-modeladmin-methods.png and b/docs/ref/contrib/admin/_images/actions-as-modeladmin-methods.png differ diff --git a/docs/ref/contrib/admin/_images/adding-actions-to-the-modeladmin.png b/docs/ref/contrib/admin/_images/adding-actions-to-the-modeladmin.png index 9510706dad..84889f9e26 100644 Binary files a/docs/ref/contrib/admin/_images/adding-actions-to-the-modeladmin.png and b/docs/ref/contrib/admin/_images/adding-actions-to-the-modeladmin.png differ diff --git a/docs/ref/contrib/admin/_images/admin-actions.png b/docs/ref/contrib/admin/_images/admin-actions.png index 7c3a6ccc2e..3750bb68dd 100644 Binary files a/docs/ref/contrib/admin/_images/admin-actions.png and b/docs/ref/contrib/admin/_images/admin-actions.png differ diff --git a/docs/ref/contrib/admin/_images/list_filter.png b/docs/ref/contrib/admin/_images/list_filter.png index 02c4879d18..cb433d4ef3 100644 Binary files a/docs/ref/contrib/admin/_images/list_filter.png and b/docs/ref/contrib/admin/_images/list_filter.png differ diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py index 89f43300d7..63e7393853 100644 --- a/tests/admin_inlines/tests.py +++ b/tests/admin_inlines/tests.py @@ -1454,12 +1454,13 @@ class TestReadOnlyChangeViewInlinePermissions(TestCase): response = self.client.get(self.change_url) self.assertContains( response, - 'Close', + '' + "Close", html=True, ) delete_link = ( - 'Delete' - "" + 'Delete' ) self.assertNotContains(response, delete_link % self.poll.id, html=True) self.assertNotContains( diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index feafde47fd..b79b4a94a4 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -2683,8 +2683,8 @@ class AdminViewPermissionsTest(TestCase): self.assertContains(response, "") self.assertContains( response, - 'Close' - "", + 'Close', ) self.assertEqual(response.context["title"], "View article") post = self.client.post(article_change_url, change_dict) @@ -2835,8 +2835,8 @@ class AdminViewPermissionsTest(TestCase): self.assertContains(response, "

    View article

    ") self.assertContains( response, - 'Close' - "", + 'Close', ) def test_change_view_save_as_new(self): @@ -4056,7 +4056,8 @@ class AdminViewStringPrimaryKeyTest(TestCase): args=(quote(self.pk),), ) self.assertContains( - response, 'History', response.text + 'History', + response.text, ) self.assertURLEqual(history_link[1], self.get_history_url()) # Check the delete link. delete_link = re.search( - 'Delete', response.text + 'Delete', response.text ) self.assertURLEqual(delete_link[1], self.get_delete_url()) @@ -8359,7 +8361,7 @@ class AdminKeepChangeListFiltersTests(TestCase): self.client.force_login(viewuser) response = self.client.get(self.get_change_url()) close_link = re.search( - 'Close', response.text + 'Close', response.text ) close_link = close_link[1].replace("&", "&") self.assertURLEqual(close_link, self.get_changelist_url()) diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index 4740cb6200..0f8b48286a 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -1089,7 +1089,9 @@ class UserChangeFormTest(TestDataMixin, TestCase): "Set password", ), ] - password_reset_link = r'([^<]*)' + password_reset_link = ( + r'([^<]*)' + ) for username, expected_help_text, expected_button_label in cases: with self.subTest(username=username): user = User.objects.get(username=username) @@ -1438,7 +1440,8 @@ class ReadOnlyPasswordHashTest(SimpleTestCase): " hash: " " WmCkn9**************************************" "

    " - '

    Reset password

    ' + '

    ' + "Reset password

    " "", ) diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index 1583f8ffd7..156520ebf7 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -1532,7 +1532,7 @@ class ChangelistTests(MessagesTestMixin, AuthViewsTestCase): response = self.client.get(user_change_url) # Test the link inside password field help_text. rel_link = re.search( - r'Reset password', + r'Reset password', response.text, )[1] self.assertEqual(urljoin(user_change_url, rel_link), password_change_url) @@ -1628,7 +1628,7 @@ class ChangelistTests(MessagesTestMixin, AuthViewsTestCase): response = self.client.get(user_change_url) # Test the link inside password field help_text. rel_link = re.search( - r'Set password', + r'Set password', response.text, )[1] self.assertEqual(urljoin(user_change_url, rel_link), password_change_url)