Loading django/core/urlresolvers.py +6 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_str, force_text, iri_to_uri from django.utils.functional import memoize, lazy from django.utils.http import urlquote from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule from django.utils.regex_helper import normalize Loading Loading @@ -379,7 +380,8 @@ class RegexURLResolver(LocaleRegexProvider): except (ImportError, AttributeError) as e: raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e)) possibilities = self.reverse_dict.getlist(lookup_view) prefix_norm, prefix_args = normalize(_prefix)[0] prefix_norm, prefix_args = normalize(urlquote(_prefix))[0] for possibility, pattern, defaults in possibilities: for result, params in possibility: if args: Loading @@ -398,8 +400,8 @@ class RegexURLResolver(LocaleRegexProvider): if not matches: continue unicode_kwargs = dict([(k, force_text(v)) for (k, v) in kwargs.items()]) candidate = (prefix_norm + result) % unicode_kwargs if re.search('^%s%s' % (_prefix, pattern), candidate, re.UNICODE): candidate = (prefix_norm.replace('%', '%%') + result) % unicode_kwargs if re.search('^%s%s' % (prefix_norm, pattern), candidate, re.UNICODE): return candidate # lookup_view can be URL label, or dotted path, or callable, Any of # these can be passed in at the top, but callables are not friendly in Loading tests/regressiontests/urlpatterns_reverse/tests.py +12 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,18 @@ class URLPatternReverse(TestCase): # Reversing None should raise an error, not return the last un-named view. self.assertRaises(NoReverseMatch, reverse, None) def test_prefix_braces(self): self.assertEqual('/%7B%7Binvalid%7D%7D/includes/non_path_include/', reverse('non_path_include', prefix='/{{invalid}}/')) def test_prefix_parenthesis(self): self.assertEqual('/bogus%29/includes/non_path_include/', reverse('non_path_include', prefix='/bogus)/')) def test_prefix_format_char(self): self.assertEqual('/bump%2520map/includes/non_path_include/', reverse('non_path_include', prefix='/bump%20map/')) class ResolverTests(unittest.TestCase): def test_resolver_repr(self): """ Loading Loading
django/core/urlresolvers.py +6 −4 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_str, force_text, iri_to_uri from django.utils.functional import memoize, lazy from django.utils.http import urlquote from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule from django.utils.regex_helper import normalize Loading Loading @@ -379,7 +380,8 @@ class RegexURLResolver(LocaleRegexProvider): except (ImportError, AttributeError) as e: raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e)) possibilities = self.reverse_dict.getlist(lookup_view) prefix_norm, prefix_args = normalize(_prefix)[0] prefix_norm, prefix_args = normalize(urlquote(_prefix))[0] for possibility, pattern, defaults in possibilities: for result, params in possibility: if args: Loading @@ -398,8 +400,8 @@ class RegexURLResolver(LocaleRegexProvider): if not matches: continue unicode_kwargs = dict([(k, force_text(v)) for (k, v) in kwargs.items()]) candidate = (prefix_norm + result) % unicode_kwargs if re.search('^%s%s' % (_prefix, pattern), candidate, re.UNICODE): candidate = (prefix_norm.replace('%', '%%') + result) % unicode_kwargs if re.search('^%s%s' % (prefix_norm, pattern), candidate, re.UNICODE): return candidate # lookup_view can be URL label, or dotted path, or callable, Any of # these can be passed in at the top, but callables are not friendly in Loading
tests/regressiontests/urlpatterns_reverse/tests.py +12 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,18 @@ class URLPatternReverse(TestCase): # Reversing None should raise an error, not return the last un-named view. self.assertRaises(NoReverseMatch, reverse, None) def test_prefix_braces(self): self.assertEqual('/%7B%7Binvalid%7D%7D/includes/non_path_include/', reverse('non_path_include', prefix='/{{invalid}}/')) def test_prefix_parenthesis(self): self.assertEqual('/bogus%29/includes/non_path_include/', reverse('non_path_include', prefix='/bogus)/')) def test_prefix_format_char(self): self.assertEqual('/bump%2520map/includes/non_path_include/', reverse('non_path_include', prefix='/bump%20map/')) class ResolverTests(unittest.TestCase): def test_resolver_repr(self): """ Loading