Skip to content

Commit 7894776

Browse files
jacobtylerwallssarahboyce
authored andcommitted
Refs #28526 -- Provided URLResolver namespace in technical 404 template.
This avoids looking up the nonexistent "name" attribute on URLResolver, which logs verbosely.
1 parent 46bd922 commit 7894776

3 files changed

Lines changed: 31 additions & 6 deletions

File tree

django/views/debug.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from django.http import Http404, HttpResponse, HttpResponseNotFound
1212
from django.template import Context, Engine, TemplateDoesNotExist
1313
from django.template.defaultfilters import pprint
14-
from django.urls import resolve
14+
from django.urls import URLResolver, resolve
1515
from django.utils import timezone
1616
from django.utils.datastructures import MultiValueDict
1717
from django.utils.encoding import force_str
@@ -635,6 +635,20 @@ def technical_404_response(request, exception):
635635
):
636636
return default_urlconf(request)
637637

638+
patterns_with_debug_info = []
639+
for urlpattern in tried or ():
640+
patterns = []
641+
for inner_pattern in urlpattern:
642+
wrapper = {"tried": inner_pattern}
643+
if isinstance(inner_pattern, URLResolver):
644+
wrapper["debug_key"] = "namespace"
645+
wrapper["debug_val"] = inner_pattern.namespace
646+
else:
647+
wrapper["debug_key"] = "name"
648+
wrapper["debug_val"] = inner_pattern.name
649+
patterns.append(wrapper)
650+
patterns_with_debug_info.append(patterns)
651+
638652
urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)
639653
if isinstance(urlconf, types.ModuleType):
640654
urlconf = urlconf.__name__
@@ -647,7 +661,8 @@ def technical_404_response(request, exception):
647661
"urlconf": urlconf,
648662
"root_urlconf": settings.ROOT_URLCONF,
649663
"request_path": error_url,
650-
"urlpatterns": tried,
664+
"urlpatterns": tried, # Unused, left for compatibility.
665+
"urlpatterns_debug": patterns_with_debug_info,
651666
"resolved": resolved,
652667
"reason": str(exception),
653668
"request": request,

django/views/templates/technical_404.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,18 @@ <h1>Page not found <small>(404)</small></h1>
4646
</header>
4747

4848
<main id="info">
49-
{% if urlpatterns %}
49+
{% if urlpatterns_debug %}
5050
<p>
5151
Using the URLconf defined in <code>{{ urlconf }}</code>,
5252
Django tried these URL patterns, in this order:
5353
</p>
5454
<ol>
55-
{% for pattern in urlpatterns %}
55+
{% for pattern in urlpatterns_debug %}
5656
<li>
5757
{% for pat in pattern %}
5858
<code>
59-
{{ pat.pattern }}
60-
{% if forloop.last and pat.name %}[name='{{ pat.name }}']{% endif %}
59+
{{ pat.tried.pattern }}
60+
{% if forloop.last and pat.debug_val %}[{{ pat.debug_key }}='{{ pat.debug_val }}']{% endif %}
6161
</code>
6262
{% endfor %}
6363
</li>

tests/view_tests/tests/test_debug.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,16 @@ def test_default_urlconf_script_name(self):
423423
response, "<h1>The install worked successfully! Congratulations!</h1>"
424424
)
425425

426+
@override_settings(ROOT_URLCONF="view_tests.default_urls")
427+
def test_default_urlconf_technical_404(self):
428+
response = self.client.get("/favicon.ico")
429+
self.assertContains(
430+
response,
431+
"<code>\nadmin/\n[namespace='admin']\n</code>",
432+
status_code=404,
433+
html=True,
434+
)
435+
426436
@override_settings(ROOT_URLCONF="view_tests.regression_21530_urls")
427437
def test_regression_21530(self):
428438
"""

0 commit comments

Comments
 (0)