A bug in reverse url lookup? (and a possible patch)

11 views
Skip to first unread message

medhat

unread,
May 26, 2006, 8:00:59 PM5/26/06
to Django developers
Hi

Reverse URL lookup
(http://groups.google.com/group/django-developers/browse_thread/thread/a5d12bc4fb073f24/83d7e4cb5f35ed08)
is one of the things that I am interested in in django.

The way I see myself using this will be roughly as follows: each
application will have a 'root' view. Using reverse URL lookup, it will
get its 'root' URL, and then the application will construct its
internal URLs using this root URL as a prefix. (of course this can
still be used for multiple 'root' URLs, the application will still know
its root views)

I was trying RegexURLResolver.reverse to accomplish that but it seemed
that (1) it did not go into included urls.py, and (2) even if it did it
will not add the prefix url from the including urls.py. I have a patch
to fix both of these problems.

I know that probably a ticket would be the best place to submit the
patch, I just wanted more people to look at it first, since I still
consider myself new with django, and I wanted to make sure that I did
not miss something, or if people will planning on using this
differently.

--
Thanks!
Medhat

Index: urlresolvers.py
===================================================================
--- urlresolvers.py (revision 2996)
+++ urlresolvers.py (working copy)
@@ -23,6 +23,25 @@
dot = callback.rindex('.')
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 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),
regex.pattern)
+ return result.replace('^', '').replace('$', '')
+
class MatchChecker(object):
"Class used in reverse RegexURLPattern lookup."
def __init__(self, args, kwargs):
@@ -108,24 +127,8 @@
return self.reverse_helper(*args, **kwargs)

def reverse_helper(self, *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:
+ return reverse_helper(self.regex, *args, **kwargs)

- >>> 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):
def __init__(self, regex, urlconf_name):
# regex is a string representing a regular expression.
@@ -180,10 +183,23 @@
def resolve500(self):
return self._resolve_special('500')

+ def reverse_helper(self, viewname, *args, **kwargs):
+ try:
+ sub_match = self.reverse(viewname, *args, **kwargs)
+ result = reverse_helper(self.regex, *args, **kwargs)
+ return result + sub_match
+ except NoReverseMatch:
+ raise NoReverseMatch
+
def reverse(self, viewname, *args, **kwargs):
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:
return pattern.reverse_helper(*args, **kwargs)
except NoReverseMatch:
continue

bradford

unread,
May 28, 2006, 7:20:00 PM5/28/06
to Django developers
I created a ticket for this: http://code.djangoproject.com/ticket/2025

Reply all
Reply to author
Forward
0 new messages