1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Improved urlresolvers so that URLconfs can be passed objects instead of strings

git-svn-id: http://code.djangoproject.com/svn/django/trunk@3554 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty
2006-08-11 07:01:29 +00:00
parent 4805675f9d
commit 0b71ffacab
2 changed files with 78 additions and 17 deletions

View File

@@ -86,10 +86,15 @@ class MatchChecker(object):
class RegexURLPattern(object):
def __init__(self, regex, callback, default_args=None):
# regex is a string representing a regular expression.
# callback is something like 'foo.views.news.stories.story_detail',
# which represents the path to a module and a view function name.
# callback is either a string like 'foo.views.news.stories.story_detail'
# which represents the path to a module and a view function name, or a
# callable object (view).
self.regex = re.compile(regex)
self.callback = callback
if callable(callback):
self._callback = callback
else:
self._callback = None
self._callback_str = callback
self.default_args = default_args or {}
def resolve(self, path):
@@ -106,23 +111,28 @@ class RegexURLPattern(object):
# In both cases, pass any extra_kwargs as **kwargs.
kwargs.update(self.default_args)
try: # Lazily load self.func.
return self.func, args, kwargs
except AttributeError:
self.func = self.get_callback()
return self.func, args, kwargs
return self.callback, args, kwargs
def get_callback(self):
mod_name, func_name = get_mod_func(self.callback)
def _get_callback(self):
if self._callback is not None:
return self._callback
mod_name, func_name = get_mod_func(self._callback_str)
try:
return getattr(__import__(mod_name, '', '', ['']), func_name)
self._callback = getattr(__import__(mod_name, '', '', ['']), func_name)
except ImportError, e:
raise ViewDoesNotExist, "Could not import %s. Error was: %s" % (mod_name, str(e))
except AttributeError, e:
raise ViewDoesNotExist, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))
return self._callback
callback = property(_get_callback)
def reverse(self, viewname, *args, **kwargs):
if viewname != self.callback:
mod_name, func_name = get_mod_func(viewname)
try:
lookup_view = getattr(__import__(mod_name, '', '', ['']), func_name)
except (ImportError, AttributeError):
raise NoReverseMatch
if lookup_view != self.callback:
raise NoReverseMatch
return self.reverse_helper(*args, **kwargs)
@@ -185,22 +195,28 @@ class RegexURLResolver(object):
def resolve500(self):
return self._resolve_special('500')
def reverse(self, viewname, *args, **kwargs):
def reverse(self, lookup_view, *args, **kwargs):
if not callable(lookup_view):
mod_name, func_name = get_mod_func(lookup_view)
try:
lookup_view = getattr(__import__(mod_name, '', '', ['']), func_name)
except (ImportError, AttributeError):
raise NoReverseMatch
for pattern in self.urlconf_module.urlpatterns:
if isinstance(pattern, RegexURLResolver):
try:
return pattern.reverse_helper(viewname, *args, **kwargs)
return pattern.reverse_helper(lookup_view, *args, **kwargs)
except NoReverseMatch:
continue
elif pattern.callback == viewname:
elif pattern.callback == lookup_view:
try:
return pattern.reverse_helper(*args, **kwargs)
except NoReverseMatch:
continue
raise NoReverseMatch
def reverse_helper(self, viewname, *args, **kwargs):
sub_match = self.reverse(viewname, *args, **kwargs)
def reverse_helper(self, lookup_view, *args, **kwargs):
sub_match = self.reverse(lookup_view, *args, **kwargs)
result = reverse_helper(self.regex, *args, **kwargs)
return result + sub_match