From 5d568bcfa66916e3de61e0090c724c899debd981 Mon Sep 17 00:00:00 2001 From: Athena Date: Thu, 27 Feb 2014 23:32:20 +0800 Subject: [PATCH] Fixed #7571 -- Fixed parameter matching in include()'d urlpattern Fixed URL resolving in the case where an outer regex includes an inner regex and both regexes use positional parameters instead of named groups, causing the outer regex's parameters to override the inner regex's. Modified the regex url resolver so that it will concatenates and then normalizes, instead of normalizing and then concatenating. --- django/core/urlresolvers.py | 6 ++---- tests/urlpatterns_reverse/included_no_kwargs_urls.py | 8 ++++++++ tests/urlpatterns_reverse/tests.py | 1 + tests/urlpatterns_reverse/urls.py | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 tests/urlpatterns_reverse/included_no_kwargs_urls.py diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py index 08aaa404935..0454b5f366c 100644 --- a/django/core/urlresolvers.py +++ b/django/core/urlresolvers.py @@ -271,12 +271,10 @@ class RegexURLResolver(LocaleRegexProvider): if pattern.app_name: apps.setdefault(pattern.app_name, []).append(pattern.namespace) else: - parent = normalize(pattern.regex.pattern) + parent_pat = pattern.regex.pattern for name in pattern.reverse_dict: 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) + new_matches = normalize(parent_pat + 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) diff --git a/tests/urlpatterns_reverse/included_no_kwargs_urls.py b/tests/urlpatterns_reverse/included_no_kwargs_urls.py new file mode 100644 index 00000000000..e408487f9b8 --- /dev/null +++ b/tests/urlpatterns_reverse/included_no_kwargs_urls.py @@ -0,0 +1,8 @@ +from django.conf.urls import patterns, url + +from .views import empty_view + + +urlpatterns = patterns('', + url(r'^inner-no-kwargs/(\d+)/', empty_view, name="inner-no-kwargs") +) diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index 02ac4e31ad0..a57b7e2a172 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -120,6 +120,7 @@ test_data = ( ('inner-extra', '/outer/42/extra/inner/', [], {'extra': 'inner', 'outer': '42'}), ('inner-extra', '/outer/42/extra/inner/', ['42', 'inner'], {}), ('inner-extra', NoReverseMatch, ['fred', 'inner'], {}), + ('inner-no-kwargs', '/outer-no-kwargs/42/inner-no-kwargs/1/', ['42', '1'], {}), ('disjunction', NoReverseMatch, ['foo'], {}), ('inner-disjunction', NoReverseMatch, ['10', '11'], {}), ('extra-places', '/e-places/10/', ['10'], {}), diff --git a/tests/urlpatterns_reverse/urls.py b/tests/urlpatterns_reverse/urls.py index d669260683b..923d0c75587 100644 --- a/tests/urlpatterns_reverse/urls.py +++ b/tests/urlpatterns_reverse/urls.py @@ -44,6 +44,7 @@ urlpatterns = patterns('', url(r'^test/1/?', empty_view, name="test"), url(r'^(?i)test/2/?$', empty_view, name="test2"), url(r'^outer/(?P\d+)/', include('urlpatterns_reverse.included_urls')), + url(r'^outer-no-kwargs/(\d+)/', include('urlpatterns_reverse.included_no_kwargs_urls')), url('', include('urlpatterns_reverse.extra_urls')), # This is non-reversible, but we shouldn't blow up when parsing it.