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)