summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanjeevholla26 <sanjeevholla26@gmail.com>2024-08-30 23:44:32 +0530
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-09-02 15:19:33 +0200
commit387475c5b2f1aa32103dbe21cb281d3b35165a0c (patch)
treec239d02a75de21531ef368e08e68ae05f68ac75a
parente4a2e22ddbf1b892144b35dc21404c164bc848c6 (diff)
Refs #35706 -- Prefixed 'Error:' to titles of admin pages with form errors.
This improves the screen reader experience.
-rw-r--r--django/contrib/admin/templates/admin/auth/user/change_password.html1
-rw-r--r--django/contrib/admin/templates/admin/change_form.html1
-rw-r--r--django/contrib/admin/templates/admin/change_list.html1
-rw-r--r--django/contrib/admin/templates/admin/login.html1
-rw-r--r--django/contrib/admin/templates/registration/password_change_form.html2
-rw-r--r--django/contrib/admin/templates/registration/password_reset_confirm.html1
-rw-r--r--django/contrib/admin/templates/registration/password_reset_form.html1
-rw-r--r--tests/admin_changelist/tests.py18
-rw-r--r--tests/admin_views/tests.py18
-rw-r--r--tests/auth_tests/test_templates.py19
10 files changed, 63 insertions, 0 deletions
diff --git a/django/contrib/admin/templates/admin/auth/user/change_password.html b/django/contrib/admin/templates/admin/auth/user/change_password.html
index 6801fe5fa7..c9a494dc19 100644
--- a/django/contrib/admin/templates/admin/auth/user/change_password.html
+++ b/django/contrib/admin/templates/admin/auth/user/change_password.html
@@ -2,6 +2,7 @@
{% load i18n static %}
{% load admin_urls %}
+{% block title %}{% if form.errors %}{{ _('Error:') }} {% endif %}{{ block.super }}{% endblock %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" href="{% static "admin/css/forms.css" %}">
diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
index 09ef954e5c..b9bde30018 100644
--- a/django/contrib/admin/templates/admin/change_form.html
+++ b/django/contrib/admin/templates/admin/change_form.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
+{% block title %}{% if errors %}{{ _('Error:') }} {% endif %}{{ block.super }}{% endblock %}
{% block extrahead %}{{ block.super }}
<script src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html
index 310872b015..fa189102bb 100644
--- a/django/contrib/admin/templates/admin/change_list.html
+++ b/django/contrib/admin/templates/admin/change_list.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_list %}
+{% block title %}{% if cl.formset and cl.formset.errors %}{{ _('Error:') }} {% endif %}{{ block.super }}{% endblock %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" href="{% static "admin/css/changelists.css" %}">
diff --git a/django/contrib/admin/templates/admin/login.html b/django/contrib/admin/templates/admin/login.html
index b61d9ec603..8c2c7d11ff 100644
--- a/django/contrib/admin/templates/admin/login.html
+++ b/django/contrib/admin/templates/admin/login.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n static %}
+{% block title %}{% if form.errors %}{{ _('Error:') }} {% endif %}{{ block.super }}{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/login.css" %}">
{{ form.media }}
{% endblock %}
diff --git a/django/contrib/admin/templates/registration/password_change_form.html b/django/contrib/admin/templates/registration/password_change_form.html
index fde2373e08..20c78210c6 100644
--- a/django/contrib/admin/templates/registration/password_change_form.html
+++ b/django/contrib/admin/templates/registration/password_change_form.html
@@ -1,5 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n static %}
+
+{% block title %}{% if form.errors %}{{ _('Error:') }} {% endif %}{{ block.super }}{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/forms.css" %}">{% endblock %}
{% block userlinks %}
{% url 'django-admindocs-docroot' as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% translate 'Documentation' %}</a> / {% endif %} {% translate 'Change password' %} /
diff --git a/django/contrib/admin/templates/registration/password_reset_confirm.html b/django/contrib/admin/templates/registration/password_reset_confirm.html
index a07645c97a..3866b5aead 100644
--- a/django/contrib/admin/templates/registration/password_reset_confirm.html
+++ b/django/contrib/admin/templates/registration/password_reset_confirm.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n static %}
+{% block title %}{% if form.new_password1.errors or form.new_password2.errors %}{{ _('Error:') }} {% endif %}{{ block.super }}{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/forms.css" %}">{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
diff --git a/django/contrib/admin/templates/registration/password_reset_form.html b/django/contrib/admin/templates/registration/password_reset_form.html
index 0edfea8ec2..7200e0f8be 100644
--- a/django/contrib/admin/templates/registration/password_reset_form.html
+++ b/django/contrib/admin/templates/registration/password_reset_form.html
@@ -1,6 +1,7 @@
{% extends "admin/base_site.html" %}
{% load i18n static %}
+{% block title %}{% if form.email.errors %}{{ _('Error:') }} {% endif %}{{ block.super }}{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/forms.css" %}">{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index ec6820c62f..694f807781 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -1264,6 +1264,24 @@ class ChangeListTests(TestCase):
# Check only the first few characters since the UUID may have dashes.
self.assertIn(str(a.pk)[:8], context.captured_queries[4]["sql"])
+ def test_list_editable_error_title(self):
+ a = Swallow.objects.create(origin="Swallow A", load=4, speed=1)
+ Swallow.objects.create(origin="Swallow B", load=2, speed=2)
+ data = {
+ "form-TOTAL_FORMS": "2",
+ "form-INITIAL_FORMS": "2",
+ "form-MIN_NUM_FORMS": "0",
+ "form-MAX_NUM_FORMS": "1000",
+ "form-0-uuid": str(a.pk),
+ "form-0-load": "invalid",
+ "_save": "Save",
+ }
+ superuser = self._create_superuser("superuser")
+ self.client.force_login(superuser)
+ changelist_url = reverse("admin:admin_changelist_swallow_changelist")
+ response = self.client.post(changelist_url, data=data)
+ self.assertContains(response, "Error: Select swallow to change")
+
def test_deterministic_order_for_unordered_model(self):
"""
The primary key is used in the ordering of the changelist's results to
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 9a031a1e51..fc1bb86d85 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -1508,6 +1508,24 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
self.assertContains(response, "<h1>Change article</h1>")
self.assertContains(response, "<h2>Article 2</h2>")
+ def test_error_in_titles(self):
+ for url, subtitle in [
+ (
+ reverse("admin:admin_views_article_change", args=(self.a1.pk,)),
+ "Article 1 | Change article",
+ ),
+ (reverse("admin:admin_views_article_add"), "Add article"),
+ (reverse("admin:login"), "Log in"),
+ (reverse("admin:password_change"), "Password change"),
+ (
+ reverse("admin:auth_user_password_change", args=(self.superuser.id,)),
+ "Change password: super",
+ ),
+ ]:
+ with self.subTest(url=url, subtitle=subtitle):
+ response = self.client.post(url, {})
+ self.assertContains(response, f"<title>Error: {subtitle}")
+
def test_view_subtitle_per_object(self):
viewuser = User.objects.create_user(
username="viewuser",
diff --git a/tests/auth_tests/test_templates.py b/tests/auth_tests/test_templates.py
index ceecfa3325..edde6ca6b4 100644
--- a/tests/auth_tests/test_templates.py
+++ b/tests/auth_tests/test_templates.py
@@ -37,6 +37,12 @@ class AuthTemplateTests(TestCase):
)
self.assertContains(response, "<h1>Password reset</h1>")
+ def test_password_reset_view_error_title(self):
+ response = self.client.post(reverse("password_reset"), {})
+ self.assertContains(
+ response, "<title>Error: Password reset | Django site admin</title>"
+ )
+
def test_password_reset_done_view(self):
response = PasswordResetDoneView.as_view()(self.request)
self.assertContains(
@@ -77,6 +83,19 @@ class AuthTemplateTests(TestCase):
'<input class="hidden" autocomplete="username" value="jsmith">',
)
+ def test_password_reset_confirm_view_error_title(self):
+ client = PasswordResetConfirmClient()
+ default_token_generator = PasswordResetTokenGenerator()
+ token = default_token_generator.make_token(self.user)
+ uidb64 = urlsafe_base64_encode(str(self.user.pk).encode())
+ url = reverse(
+ "password_reset_confirm", kwargs={"uidb64": uidb64, "token": token}
+ )
+ response = client.post(url, {})
+ self.assertContains(
+ response, "<title>Error: Enter new password | Django site admin</title>"
+ )
+
@override_settings(AUTH_USER_MODEL="auth_tests.CustomUser")
def test_password_reset_confirm_view_custom_username_hint(self):
custom_user = CustomUser.custom_objects.create_user(