diff --git a/AUTHORS b/AUTHORS index 615aa7b7f7..8c903ff6c5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -638,6 +638,7 @@ answer newbie questions, and generally made Django that much better: Marc Tamlyn Marc-Aurèle Brothier Marian Andre + Marijke Luttekes Marijn Vriens Mario Gonzalez Mariusz Felisiak diff --git a/django/views/templates/technical_404.html b/django/views/templates/technical_404.html index c47dae22af..f2bfe49372 100644 --- a/django/views/templates/technical_404.html +++ b/django/views/templates/technical_404.html @@ -9,9 +9,9 @@ body * { padding:10px 20px; } body * * { padding:0; } body { font:small sans-serif; background:#eee; color:#000; } - body>div { border-bottom:1px solid #ddd; } + body > :where(header, main, footer) { border-bottom:1px solid #ddd; } h1 { font-weight:normal; margin-bottom:.4em; } - h1 span { font-size:60%; color:#666; font-weight:normal; } + h1 small { font-size:60%; color:#666; font-weight:normal; } table { border:none; border-collapse: collapse; width:100%; } td, th { vertical-align:top; padding:2px 3px; } th { width:12em; text-align:right; color:#666; padding-right:.5em; } @@ -24,27 +24,28 @@ -
-

Page not found (404)

+
+

Page not found (404)

{% if reason and resolved %}
{{ reason }}
{% endif %} - + - + {% if raising_view_name %} - + {% endif %}
Request Method:Request Method: {{ request.META.REQUEST_METHOD }}
Request URL:Request URL: {{ request.build_absolute_uri }}
Raised by:Raised by: {{ raising_view_name }}
-
-
+ + +
{% if urlpatterns %}

Using the URLconf defined in {{ urlconf }}, @@ -54,8 +55,10 @@ {% for pattern in urlpatterns %}

  • {% for pat in pattern %} + {{ pat.pattern }} {% if forloop.last and pat.name %}[name='{{ pat.name }}']{% endif %} + {% endfor %}
  • {% endfor %} @@ -69,14 +72,14 @@ {% if resolved %}matched the last one.{% else %}didn’t match any of these.{% endif %}

    {% endif %} -
    + -
    +

    You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

    -
    + diff --git a/django/views/templates/technical_500.html b/django/views/templates/technical_500.html index a5c187147b..305c4655ad 100644 --- a/django/views/templates/technical_500.html +++ b/django/views/templates/technical_500.html @@ -10,7 +10,7 @@ body * { padding:10px 20px; } body * * { padding:0; } body { font:small sans-serif; background-color:#fff; color:#000; } - body>div { border-bottom:1px solid #ddd; } + body > :where(header, main, footer) { border-bottom:1px solid #ddd; } h1 { font-weight:normal; } h2 { margin-bottom:.8em; } h3 { margin:1em 0 .5em 0; } @@ -47,6 +47,8 @@ .user div.commands a { color: black; } #summary { background: #ffc; } #summary h2 { font-weight: normal; color: #666; } + #info { padding: 0; } + #info > * { padding:10px 20px; } #explanation { background:#eee; } #template, #template-not-exist { background:#f6f6f6; } #template-not-exist ul { margin: 0 0 10px 20px; } @@ -97,67 +99,69 @@ {% endif %} -
    +

    {% if exception_type %}{{ exception_type }}{% else %}Report{% endif %} {% if request %} at {{ request.path_info }}{% endif %}

    {% if exception_value %}{{ exception_value|force_escape }}{% if exception_notes %}{{ exception_notes }}{% endif %}{% else %}No exception message supplied{% endif %}
    {% if request %} - + - + {% endif %} - + {% if exception_type %} - + {% endif %} {% if exception_type and exception_value %} - + {% endif %} {% if lastframe %} - + {% endif %} {% if raising_view_name %} - + {% endif %} - + - + - - + + - +
    Request Method:Request Method: {{ request.META.REQUEST_METHOD }}
    Request URL:Request URL: {{ request_insecure_uri }}
    Django Version:Django Version: {{ django_version_info }}
    Exception Type:Exception Type: {{ exception_type }}
    Exception Value:Exception Value:
    {{ exception_value|force_escape }}
    Exception Location:Exception Location: {{ lastframe.filename }}, line {{ lastframe.lineno }}, in {{ lastframe.function }}
    Raised during:Raised during: {{ raising_view_name }}
    Python Executable:Python Executable: {{ sys_executable }}
    Python Version:Python Version: {{ sys_version_info }}
    Python Path:
    {{ sys_path|pprint }}
    Python Path:
    {{ sys_path|pprint }}
    Server time:Server time: {{server_time|date:"r"}}
    -
    + + +
    {% if unicode_hint %}

    Unicode error hint

    @@ -195,11 +199,11 @@ {% if template_info.bottom != template_info.total %} cut-bottom{% endif %}"> {% for source_line in template_info.source_lines %} {% if source_line.0 == template_info.line %} - {{ source_line.0 }} + {{ source_line.0 }} {{ template_info.before }}{{ template_info.during }}{{ template_info.after }} {% else %} - {{ source_line.0 }} + {{ source_line.0 }} {{ source_line.1 }} {% endif %} {% endfor %} @@ -266,8 +270,8 @@ - - + + @@ -354,8 +358,8 @@ Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ ex
    VariableValueVariableValue
    - - + + @@ -376,8 +380,8 @@ Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ ex
    VariableValueVariableValue
    - - + + @@ -398,8 +402,8 @@ Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ ex
    VariableValueVariableValue
    - - + + @@ -420,8 +424,8 @@ Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ ex
    VariableValueVariableValue
    - - + + @@ -441,8 +445,8 @@ Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ ex
    VariableValueVariableValue
    - - + + @@ -463,8 +467,8 @@ Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ ex
    VariableValueVariableValue
    - - + + @@ -478,14 +482,16 @@ Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ ex
    SettingValueSettingValue
    +
    + {% if not is_email %} -
    +

    You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard page generated by the handler for this status code.

    -
    + {% endif %} diff --git a/docs/releases/5.1.txt b/docs/releases/5.1.txt index 284c1f4f74..f166474607 100644 --- a/docs/releases/5.1.txt +++ b/docs/releases/5.1.txt @@ -156,7 +156,8 @@ Email Error Reporting ~~~~~~~~~~~~~~~ -* ... +* In order to improve accessibility, the technical 404 and 500 error pages now + use HTML landmark elements for the header, footer, and main content areas. File Storage ~~~~~~~~~~~~ diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 03db07a61c..45a0dc70ee 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -176,6 +176,12 @@ class DebugViewTests(SimpleTestCase): self.assertContains( response, "Django tried these URL patterns", status_code=404 ) + self.assertContains( + response, + "technical404/ [name='my404']", + status_code=404, + html=True, + ) self.assertContains( response, "

    The current path, not-in-urls, didn’t match any " @@ -204,6 +210,9 @@ class DebugViewTests(SimpleTestCase): def test_technical_404(self): response = self.client.get("/technical404/") + self.assertContains(response, '

    ', status_code=404) + self.assertContains(response, '
    ', status_code=404) + self.assertContains(response, '