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.
This commit is contained in:
Athena 2014-02-27 23:32:20 +08:00 committed by Baptiste Mispelon
parent a248c88372
commit 5d568bcfa6
4 changed files with 12 additions and 4 deletions

View File

@ -271,12 +271,10 @@ class RegexURLResolver(LocaleRegexProvider):
if pattern.app_name: if pattern.app_name:
apps.setdefault(pattern.app_name, []).append(pattern.namespace) apps.setdefault(pattern.app_name, []).append(pattern.namespace)
else: else:
parent = normalize(pattern.regex.pattern) parent_pat = pattern.regex.pattern
for name in pattern.reverse_dict: for name in pattern.reverse_dict:
for matches, pat, defaults in pattern.reverse_dict.getlist(name): for matches, pat, defaults in pattern.reverse_dict.getlist(name):
new_matches = [] new_matches = normalize(parent_pat + pat)
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, dict(defaults, **pattern.default_kwargs))) lookups.appendlist(name, (new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs)))
for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items(): for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items():
namespaces[namespace] = (p_pattern + prefix, sub_pattern) namespaces[namespace] = (p_pattern + prefix, sub_pattern)

View File

@ -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")
)

View File

@ -120,6 +120,7 @@ test_data = (
('inner-extra', '/outer/42/extra/inner/', [], {'extra': 'inner', 'outer': '42'}), ('inner-extra', '/outer/42/extra/inner/', [], {'extra': 'inner', 'outer': '42'}),
('inner-extra', '/outer/42/extra/inner/', ['42', 'inner'], {}), ('inner-extra', '/outer/42/extra/inner/', ['42', 'inner'], {}),
('inner-extra', NoReverseMatch, ['fred', 'inner'], {}), ('inner-extra', NoReverseMatch, ['fred', 'inner'], {}),
('inner-no-kwargs', '/outer-no-kwargs/42/inner-no-kwargs/1/', ['42', '1'], {}),
('disjunction', NoReverseMatch, ['foo'], {}), ('disjunction', NoReverseMatch, ['foo'], {}),
('inner-disjunction', NoReverseMatch, ['10', '11'], {}), ('inner-disjunction', NoReverseMatch, ['10', '11'], {}),
('extra-places', '/e-places/10/', ['10'], {}), ('extra-places', '/e-places/10/', ['10'], {}),

View File

@ -44,6 +44,7 @@ urlpatterns = patterns('',
url(r'^test/1/?', empty_view, name="test"), url(r'^test/1/?', empty_view, name="test"),
url(r'^(?i)test/2/?$', empty_view, name="test2"), url(r'^(?i)test/2/?$', empty_view, name="test2"),
url(r'^outer/(?P<outer>\d+)/', include('urlpatterns_reverse.included_urls')), url(r'^outer/(?P<outer>\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')), url('', include('urlpatterns_reverse.extra_urls')),
# This is non-reversible, but we shouldn't blow up when parsing it. # This is non-reversible, but we shouldn't blow up when parsing it.