Ticket #2025: reverse_url_lookup.patch

File reverse_url_lookup.patch, 3.3 KB (added by medhat, 18 years ago)

Patch to make reverse url lookup go into included urls.py

  • urlresolvers.py

     
    2323    dot = callback.rindex('.')
    2424    return callback[:dot], callback[dot+1:]
    2525
     26def reverse_helper(regex, *args, **kwargs):
     27    """
     28    Does a "reverse" lookup -- returns the URL for the given args/kwargs.
     29    The args/kwargs are applied to the regular expression in this
     30    RegexURLPattern. For example:
     31
     32        >>> RegexURLPattern('^places/(\d+)/$').reverse_helper(3)
     33        'places/3/'
     34        >>> RegexURLPattern('^places/(?P<id>\d+)/$').reverse_helper(id=3)
     35        'places/3/'
     36        >>> RegexURLPattern('^people/(?P<state>\w\w)/(\w+)/$').reverse_helper('adrian', state='il')
     37        'people/il/adrian/'
     38
     39    Raises NoReverseMatch if the args/kwargs aren't valid for the RegexURLPattern.
     40    """
     41    # TODO: Handle nested parenthesis in the following regex.
     42    result = re.sub(r'\(([^)]+)\)', MatchChecker(args, kwargs), regex.pattern)
     43    return result.replace('^', '').replace('$', '')
     44
    2645class MatchChecker(object):
    2746    "Class used in reverse RegexURLPattern lookup."
    2847    def __init__(self, args, kwargs):
     
    108127        return self.reverse_helper(*args, **kwargs)
    109128
    110129    def reverse_helper(self, *args, **kwargs):
    111         """
    112         Does a "reverse" lookup -- returns the URL for the given args/kwargs.
    113         The args/kwargs are applied to the regular expression in this
    114         RegexURLPattern. For example:
     130        return reverse_helper(self.regex, *args, **kwargs)
    115131
    116             >>> RegexURLPattern('^places/(\d+)/$').reverse_helper(3)
    117             'places/3/'
    118             >>> RegexURLPattern('^places/(?P<id>\d+)/$').reverse_helper(id=3)
    119             'places/3/'
    120             >>> RegexURLPattern('^people/(?P<state>\w\w)/(\w+)/$').reverse_helper('adrian', state='il')
    121             'people/il/adrian/'
    122 
    123         Raises NoReverseMatch if the args/kwargs aren't valid for the RegexURLPattern.
    124         """
    125         # TODO: Handle nested parenthesis in the following regex.
    126         result = re.sub(r'\(([^)]+)\)', MatchChecker(args, kwargs), self.regex.pattern)
    127         return result.replace('^', '').replace('$', '')
    128 
    129132class RegexURLResolver(object):
    130133    def __init__(self, regex, urlconf_name):
    131134        # regex is a string representing a regular expression.
     
    180183    def resolve500(self):
    181184        return self._resolve_special('500')
    182185
     186    def reverse_helper(self, viewname, *args, **kwargs):
     187        try:
     188            sub_match = self.reverse(viewname, *args, **kwargs)
     189            result = reverse_helper(self.regex, *args, **kwargs)
     190            return result + sub_match
     191        except NoReverseMatch:
     192            raise NoReverseMatch
     193
    183194    def reverse(self, viewname, *args, **kwargs):
    184195        for pattern in self.urlconf_module.urlpatterns:
    185             if pattern.callback == viewname:
     196            if isinstance(pattern, RegexURLResolver):
    186197                try:
     198                    return pattern.reverse_helper(viewname, *args, **kwargs)
     199                except NoReverseMatch:
     200                    continue
     201            elif pattern.callback == viewname:
     202                try:
    187203                    return pattern.reverse_helper(*args, **kwargs)
    188204                except NoReverseMatch:
    189205                    continue
Back to Top