summaryrefslogtreecommitdiff
path: root/django/urls
diff options
context:
space:
mode:
authorAlokik Vijay <alokik.roe@gmail.com>2022-03-28 21:26:20 +0530
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-03-29 10:27:40 +0200
commitbaf9604ed8fed3e6e7ddfaca2d83c377c81399ae (patch)
tree141aee743c3cae65e6e4522859489d3c0da1d4aa /django/urls
parent83c803f161044fbfbfcd9a0c94ca93dc131be662 (diff)
Fixed #16406 -- Added ResolveMatch.captured_kwargs and extra_kwargs.
Thanks Florian Apolloner for the review and implementation idea.
Diffstat (limited to 'django/urls')
-rw-r--r--django/urls/resolvers.py38
1 files changed, 32 insertions, 6 deletions
diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py
index 26c9884e18..9f42e2738c 100644
--- a/django/urls/resolvers.py
+++ b/django/urls/resolvers.py
@@ -41,6 +41,8 @@ class ResolverMatch:
namespaces=None,
route=None,
tried=None,
+ captured_kwargs=None,
+ extra_kwargs=None,
):
self.func = func
self.args = args
@@ -48,6 +50,8 @@ class ResolverMatch:
self.url_name = url_name
self.route = route
self.tried = tried
+ self.captured_kwargs = captured_kwargs
+ self.extra_kwargs = extra_kwargs
# If a URLRegexResolver doesn't have a namespace or app_name, it passes
# in an empty value.
@@ -78,7 +82,7 @@ class ResolverMatch:
func = self._func_path
return (
"ResolverMatch(func=%s, args=%r, kwargs=%r, url_name=%r, "
- "app_names=%r, namespaces=%r, route=%r)"
+ "app_names=%r, namespaces=%r, route=%r%s%s)"
% (
func,
self.args,
@@ -87,6 +91,10 @@ class ResolverMatch:
self.app_names,
self.namespaces,
self.route,
+ f", captured_kwargs={self.captured_kwargs!r}"
+ if self.captured_kwargs
+ else "",
+ f", extra_kwargs={self.extra_kwargs!r}" if self.extra_kwargs else "",
)
)
@@ -416,11 +424,17 @@ class URLPattern:
def resolve(self, path):
match = self.pattern.match(path)
if match:
- new_path, args, kwargs = match
- # Pass any extra_kwargs as **kwargs.
- kwargs.update(self.default_args)
+ new_path, args, captured_kwargs = match
+ # Pass any default args as **kwargs.
+ kwargs = {**captured_kwargs, **self.default_args}
return ResolverMatch(
- self.callback, args, kwargs, self.pattern.name, route=str(self.pattern)
+ self.callback,
+ args,
+ kwargs,
+ self.pattern.name,
+ route=str(self.pattern),
+ captured_kwargs=captured_kwargs,
+ extra_kwargs=self.default_args,
)
@cached_property
@@ -678,6 +692,11 @@ class URLResolver:
[self.namespace] + sub_match.namespaces,
self._join_route(current_route, sub_match.route),
tried,
+ captured_kwargs=sub_match.captured_kwargs,
+ extra_kwargs={
+ **self.default_kwargs,
+ **sub_match.extra_kwargs,
+ },
)
tried.append([pattern])
raise Resolver404({"tried": tried, "path": new_path})
@@ -737,7 +756,14 @@ class URLResolver:
else:
if set(kwargs).symmetric_difference(params).difference(defaults):
continue
- if any(kwargs.get(k, v) != v for k, v in defaults.items()):
+ matches = True
+ for k, v in defaults.items():
+ if k in params:
+ continue
+ if kwargs.get(k, v) != v:
+ matches = False
+ break
+ if not matches:
continue
candidate_subs = kwargs
# Convert the candidate subs to text using Converter.to_url().