Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed #2025 -- Fixed some issues with URL reversal, which still isn't…
… ready for prime time. Thanks, medhat

git-svn-id: http://code.djangoproject.com/svn/django/trunk@3057 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
adrianholovaty committed Jun 2, 2006
1 parent 927d4fb commit bd5b350
Showing 1 changed file with 31 additions and 18 deletions.
49 changes: 31 additions & 18 deletions django/core/urlresolvers.py
Expand Up @@ -23,6 +23,25 @@ def get_mod_func(callback):
dot = callback.rindex('.') dot = callback.rindex('.')
return callback[:dot], callback[dot+1:] return callback[:dot], callback[dot+1:]


def reverse_helper(regex, *args, **kwargs):
"""
Does a "reverse" lookup -- returns the URL for the given args/kwargs.
The args/kwargs are applied to the given compiled regular expression.
For example:
>>> reverse_helper(re.compile('^places/(\d+)/$'), 3)
'places/3/'
>>> reverse_helper(re.compile('^places/(?P<id>\d+)/$'), id=3)
'places/3/'
>>> reverse_helper(re.compile('^people/(?P<state>\w\w)/(\w+)/$'), 'adrian', state='il')
'people/il/adrian/'
Raises NoReverseMatch if the args/kwargs aren't valid for the regex.
"""
# TODO: Handle nested parenthesis in the following regex.
result = re.sub(r'\(([^)]+)\)', MatchChecker(args, kwargs), regex.pattern)
return result.replace('^', '').replace('$', '')

class MatchChecker(object): class MatchChecker(object):
"Class used in reverse RegexURLPattern lookup." "Class used in reverse RegexURLPattern lookup."
def __init__(self, args, kwargs): def __init__(self, args, kwargs):
Expand Down Expand Up @@ -108,23 +127,7 @@ def reverse(self, viewname, *args, **kwargs):
return self.reverse_helper(*args, **kwargs) return self.reverse_helper(*args, **kwargs)


def reverse_helper(self, *args, **kwargs): def reverse_helper(self, *args, **kwargs):
""" return reverse_helper(self.regex, *args, **kwargs)
Does a "reverse" lookup -- returns the URL for the given args/kwargs.
The args/kwargs are applied to the regular expression in this
RegexURLPattern. For example:
>>> RegexURLPattern('^places/(\d+)/$').reverse_helper(3)
'places/3/'
>>> RegexURLPattern('^places/(?P<id>\d+)/$').reverse_helper(id=3)
'places/3/'
>>> RegexURLPattern('^people/(?P<state>\w\w)/(\w+)/$').reverse_helper('adrian', state='il')
'people/il/adrian/'
Raises NoReverseMatch if the args/kwargs aren't valid for the RegexURLPattern.
"""
# TODO: Handle nested parenthesis in the following regex.
result = re.sub(r'\(([^)]+)\)', MatchChecker(args, kwargs), self.regex.pattern)
return result.replace('^', '').replace('$', '')


class RegexURLResolver(object): class RegexURLResolver(object):
def __init__(self, regex, urlconf_name): def __init__(self, regex, urlconf_name):
Expand Down Expand Up @@ -182,9 +185,19 @@ def resolve500(self):


def reverse(self, viewname, *args, **kwargs): def reverse(self, viewname, *args, **kwargs):
for pattern in self.urlconf_module.urlpatterns: for pattern in self.urlconf_module.urlpatterns:
if pattern.callback == viewname: if isinstance(pattern, RegexURLResolver):
try:
return pattern.reverse_helper(viewname, *args, **kwargs)
except NoReverseMatch:
continue
elif pattern.callback == viewname:
try: try:
return pattern.reverse_helper(*args, **kwargs) return pattern.reverse_helper(*args, **kwargs)
except NoReverseMatch: except NoReverseMatch:
continue continue
raise NoReverseMatch raise NoReverseMatch

def reverse_helper(self, viewname, *args, **kwargs):
sub_match = self.reverse(viewname, *args, **kwargs)
result = reverse_helper(self.regex, *args, **kwargs)
return result + sub_match

0 comments on commit bd5b350

Please sign in to comment.