summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis Leidel <jannis@leidel.info>2011-05-07 16:59:25 +0000
committerJannis Leidel <jannis@leidel.info>2011-05-07 16:59:25 +0000
commitfe96214939b76d1e7389b1c569d833e96e3a5074 (patch)
treef419fd4a787898de506bcc01e15f325eb8f6c582
parenteb24b546340d500502278bd124dbd527963ca4c4 (diff)
Fixed #13154 -- Fixed the URL resolver's reverse() to match the behavior of its resolve() with regard to the default kwargs. Many thanks to patrys.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16177 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/core/urlresolvers.py19
-rw-r--r--tests/regressiontests/urlpatterns_reverse/tests.py7
-rw-r--r--tests/regressiontests/urlpatterns_reverse/urls.py8
-rw-r--r--tests/regressiontests/urlpatterns_reverse/views.py3
4 files changed, 28 insertions, 9 deletions
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index 34bca8ae80..424886e68b 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -206,20 +206,20 @@ class RegexURLResolver(object):
else:
parent = normalize(pattern.regex.pattern)
for name in pattern.reverse_dict:
- for matches, pat in pattern.reverse_dict.getlist(name):
+ for matches, pat, defaults in pattern.reverse_dict.getlist(name):
new_matches = []
for piece, p_args in parent:
new_matches.extend([(piece + suffix, p_args + args) for (suffix, args) in matches])
- lookups.appendlist(name, (new_matches, p_pattern + pat))
+ lookups.appendlist(name, (new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs)))
for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items():
namespaces[namespace] = (p_pattern + prefix, sub_pattern)
for app_name, namespace_list in pattern.app_dict.items():
apps.setdefault(app_name, []).extend(namespace_list)
else:
bits = normalize(p_pattern)
- lookups.appendlist(pattern.callback, (bits, p_pattern))
+ lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args))
if pattern.name is not None:
- lookups.appendlist(pattern.name, (bits, p_pattern))
+ lookups.appendlist(pattern.name, (bits, p_pattern, pattern.default_args))
self._reverse_dict = lookups
self._namespace_dict = namespaces
self._app_dict = apps
@@ -310,7 +310,7 @@ class RegexURLResolver(object):
except (ImportError, AttributeError), e:
raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e))
possibilities = self.reverse_dict.getlist(lookup_view)
- for possibility, pattern in possibilities:
+ for possibility, pattern, defaults in possibilities:
for result, params in possibility:
if args:
if len(args) != len(params):
@@ -318,7 +318,14 @@ class RegexURLResolver(object):
unicode_args = [force_unicode(val) for val in args]
candidate = result % dict(zip(params, unicode_args))
else:
- if set(kwargs.keys()) != set(params):
+ if set(kwargs.keys() + defaults.keys()) != set(params + defaults.keys()):
+ continue
+ matches = True
+ for k, v in defaults.items():
+ if kwargs.get(k, v) != v:
+ matches = False
+ break
+ if not matches:
continue
unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
candidate = result % unicode_kwargs
diff --git a/tests/regressiontests/urlpatterns_reverse/tests.py b/tests/regressiontests/urlpatterns_reverse/tests.py
index 4f391d9653..31a928caa2 100644
--- a/tests/regressiontests/urlpatterns_reverse/tests.py
+++ b/tests/regressiontests/urlpatterns_reverse/tests.py
@@ -127,8 +127,13 @@ test_data = (
('kwargs_view', '/arg_view/10/', [], {'arg1':10}),
('regressiontests.urlpatterns_reverse.views.absolute_kwargs_view', '/absolute_arg_view/', [], {}),
('regressiontests.urlpatterns_reverse.views.absolute_kwargs_view', '/absolute_arg_view/10/', [], {'arg1':10}),
- ('non_path_include', '/includes/non_path_include/', [], {})
+ ('non_path_include', '/includes/non_path_include/', [], {}),
+ # Tests for #13154
+ ('defaults', '/defaults_view1/3/', [], {'arg1': 3, 'arg2': 1}),
+ ('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}),
+ ('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}),
+ ('defaults', NoReverseMatch, [], {'arg2': 1}),
)
class NoURLPatternsTests(TestCase):
diff --git a/tests/regressiontests/urlpatterns_reverse/urls.py b/tests/regressiontests/urlpatterns_reverse/urls.py
index c603c0235a..ba59cf8f9a 100644
--- a/tests/regressiontests/urlpatterns_reverse/urls.py
+++ b/tests/regressiontests/urlpatterns_reverse/urls.py
@@ -19,7 +19,7 @@ urlpatterns = patterns('',
url(r'^people/(?:name/)', empty_view, name="people2"),
url(r'^people/(?:name/(\w+)/)?', empty_view, name="people2a"),
url(r'^optional/(?P<name>.*)/(?:.+/)?', empty_view, name="optional"),
- url(r'^hardcoded/$', 'hardcoded/', empty_view, name="hardcoded"),
+ url(r'^hardcoded/$', empty_view, name="hardcoded"),
url(r'^hardcoded/doc\.pdf$', empty_view, name="hardcoded2"),
url(r'^people/(?P<state>\w\w)/(?P<name>\w+)/$', empty_view, name="people3"),
url(r'^people/(?P<state>\w\w)/(?P<name>\d)/$', empty_view, name="people4"),
@@ -55,7 +55,11 @@ urlpatterns = patterns('',
url(r'arg_view/(?P<arg1>\d+)/$', 'kwargs_view'),
url(r'absolute_arg_view/(?P<arg1>\d+)/$', absolute_kwargs_view),
url(r'absolute_arg_view/$', absolute_kwargs_view),
-
+
+ # Tests for #13154. Mixed syntax to test both ways of defining URLs.
+ url(r'defaults_view1/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 1}, name='defaults'),
+ (r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'),
+
url('^includes/', include(other_patterns)),
)
diff --git a/tests/regressiontests/urlpatterns_reverse/views.py b/tests/regressiontests/urlpatterns_reverse/views.py
index b04bf33ff1..538c6231a2 100644
--- a/tests/regressiontests/urlpatterns_reverse/views.py
+++ b/tests/regressiontests/urlpatterns_reverse/views.py
@@ -13,6 +13,9 @@ def kwargs_view(request, arg1=1, arg2=2):
def absolute_kwargs_view(request, arg1=1, arg2=2):
return HttpResponse('')
+def defaults_view(request, arg1, arg2):
+ pass
+
class ViewClass(object):
def __call__(self, request, *args, **kwargs):
return HttpResponse('')