summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2020-07-07 16:23:54 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-09-07 06:54:19 +0200
commit11ebc6479ffda87376b60c9475d33d8120f86368 (patch)
treeccc77bccff2f90a3b16b887f975e08cbdbcf5419 /django
parent83dea65ed649b5e80111017cd5c476c636872b2d (diff)
Fixed #31791 -- Made technical 404 debug page display the tried URL patterns for Http404.
Diffstat (limited to 'django')
-rw-r--r--django/urls/resolvers.py20
-rw-r--r--django/views/debug.py5
-rw-r--r--django/views/templates/technical_404.html7
3 files changed, 22 insertions, 10 deletions
diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py
index 5e3e6dea16..2a9dc11f28 100644
--- a/django/urls/resolvers.py
+++ b/django/urls/resolvers.py
@@ -30,12 +30,13 @@ from .utils import get_callable
class ResolverMatch:
- def __init__(self, func, args, kwargs, url_name=None, app_names=None, namespaces=None, route=None):
+ def __init__(self, func, args, kwargs, url_name=None, app_names=None, namespaces=None, route=None, tried=None):
self.func = func
self.args = args
self.kwargs = kwargs
self.url_name = url_name
self.route = route
+ self.tried = tried
# If a URLRegexResolver doesn't have a namespace or app_name, it passes
# in an empty value.
@@ -526,6 +527,13 @@ class URLResolver:
return self._app_dict[language_code]
@staticmethod
+ def _extend_tried(tried, pattern, sub_tried=None):
+ if sub_tried is None:
+ tried.append([pattern])
+ else:
+ tried.extend([pattern, *t] for t in sub_tried)
+
+ @staticmethod
def _join_route(route1, route2):
"""Join two routes, without the starting ^ in the second route."""
if not route1:
@@ -549,11 +557,7 @@ class URLResolver:
try:
sub_match = pattern.resolve(new_path)
except Resolver404 as e:
- sub_tried = e.args[0].get('tried')
- if sub_tried is not None:
- tried.extend([pattern] + t for t in sub_tried)
- else:
- tried.append([pattern])
+ self._extend_tried(tried, pattern, e.args[0].get('tried'))
else:
if sub_match:
# Merge captured arguments in match with submatch
@@ -566,6 +570,7 @@ class URLResolver:
if not sub_match_dict:
sub_match_args = args + sub_match.args
current_route = '' if isinstance(pattern, URLPattern) else str(pattern.pattern)
+ self._extend_tried(tried, pattern, sub_match.tried)
return ResolverMatch(
sub_match.func,
sub_match_args,
@@ -574,8 +579,9 @@ class URLResolver:
[self.app_name] + sub_match.app_names,
[self.namespace] + sub_match.namespaces,
self._join_route(current_route, sub_match.route),
+ tried,
)
- tried.append([pattern])
+ self._extend_tried(tried, pattern)
raise Resolver404({'tried': tried, 'path': new_path})
raise Resolver404({'path': path})
diff --git a/django/views/debug.py b/django/views/debug.py
index e45ef01ace..7a89f7bd15 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -481,8 +481,10 @@ def technical_404_response(request, exception):
try:
tried = exception.args[0]['tried']
except (IndexError, TypeError, KeyError):
- tried = []
+ resolved = True
+ tried = request.resolver_match.tried if request.resolver_match else None
else:
+ resolved = False
if (not tried or ( # empty URLconf
request.path == '/' and
len(tried) == 1 and # default URLconf
@@ -520,6 +522,7 @@ def technical_404_response(request, exception):
'root_urlconf': settings.ROOT_URLCONF,
'request_path': error_url,
'urlpatterns': tried,
+ 'resolved': resolved,
'reason': str(exception),
'request': request,
'settings': reporter_filter.get_safe_settings(),
diff --git a/django/views/templates/technical_404.html b/django/views/templates/technical_404.html
index 694309aa13..077bb20964 100644
--- a/django/views/templates/technical_404.html
+++ b/django/views/templates/technical_404.html
@@ -60,8 +60,11 @@
</ol>
<p>
{% if request_path %}
- The current path, <code>{{ request_path }}</code>,{% else %}
- The empty path{% endif %} didn’t match any of these.
+ The current path, <code>{{ request_path }}</code>,
+ {% else %}
+ The empty path
+ {% endif %}
+ {% if resolved %}matched the last one.{% else %}didn’t match any of these.{% endif %}
</p>
{% else %}
<p>{{ reason }}</p>