Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactored the internals of URL parsing to use less code

git-svn-id: http://code.djangoproject.com/svn/django/trunk@411 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit a55598cbdd5e8ab58bb58e2178ccbe155526d735 1 parent 888cf1f
@adrianholovaty adrianholovaty authored
View
4 django/conf/urls/defaults.py
@@ -1,4 +1,4 @@
-from django.core.urlresolvers import RegexURLMultiplePattern, RegexURLPattern
+from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
__all__ = ['handler404', 'handler500', 'include', 'patterns']
@@ -11,7 +11,7 @@ def patterns(prefix, *tuples):
pattern_list = []
for t in tuples:
if type(t[1]) == list:
- pattern_list.append(RegexURLMultiplePattern(t[0], t[1][0]))
+ pattern_list.append(RegexURLResolver(t[0], t[1][0]))
else:
pattern_list.append(RegexURLPattern(t[0], prefix and (prefix + '.' + t[1]) or t[1], *t[2:]))
return pattern_list
View
15 django/core/handlers/base.py
@@ -51,8 +51,7 @@ def get_response(self, path, request):
if response:
return response
- conf_module = __import__(ROOT_URLCONF, '', '', [''])
- resolver = urlresolvers.RegexURLResolver(conf_module.urlpatterns)
+ resolver = urlresolvers.RegexURLResolver(r'^/', ROOT_URLCONF)
try:
callback, param_dict = resolver.resolve(path)
# Apply view middleware
@@ -65,8 +64,7 @@ def get_response(self, path, request):
if DEBUG:
return self.get_technical_error_response(is404=True)
else:
- resolver = urlresolvers.Error404Resolver(conf_module.handler404)
- callback, param_dict = resolver.resolve()
+ callback, param_dict = resolver.resolve404()
return callback(request, **param_dict)
except db.DatabaseError:
db.db.rollback()
@@ -76,7 +74,7 @@ def get_response(self, path, request):
subject = 'Database error (%s IP)' % (request.META['REMOTE_ADDR'] in INTERNAL_IPS and 'internal' or 'EXTERNAL')
message = "%s\n\n%s" % (self._get_traceback(), request)
mail_admins(subject, message, fail_silently=True)
- return self.get_friendly_error_response(request, conf_module)
+ return self.get_friendly_error_response(request, resolver)
except exceptions.PermissionDenied:
return httpwrappers.HttpResponseForbidden('<h1>Permission denied</h1>')
except: # Handle everything else, including SuspiciousOperation, etc.
@@ -90,16 +88,15 @@ def get_response(self, path, request):
request_repr = "Request repr() unavailable"
message = "%s\n\n%s" % (self._get_traceback(), request_repr)
mail_admins(subject, message, fail_silently=True)
- return self.get_friendly_error_response(request, conf_module)
+ return self.get_friendly_error_response(request, resolver)
- def get_friendly_error_response(self, request, conf_module):
+ def get_friendly_error_response(self, request, resolver):
"""
Returns an HttpResponse that displays a PUBLIC error message for a
fundamental database or coding error.
"""
from django.core import urlresolvers
- resolver = urlresolvers.Error404Resolver(conf_module.handler500)
- callback, param_dict = resolver.resolve()
+ callback, param_dict = resolver.resolve500()
return callback(request, **param_dict)
def get_technical_error_response(self, is404=False):
View
71 django/core/urlresolvers.py
@@ -18,13 +18,14 @@ def get_mod_func(callback):
class RegexURLPattern:
def __init__(self, regex, callback, default_args=None):
- self.regex = re.compile(regex)
+ # 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.
+ self.regex = re.compile(regex)
self.callback = callback
self.default_args = default_args or {}
- def search(self, path):
+ def resolve(self, path):
match = self.regex.search(path)
if match:
args = dict(match.groupdict(), **self.default_args)
@@ -43,56 +44,44 @@ def get_callback(self):
except AttributeError, e:
raise ViewDoesNotExist, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))
-class RegexURLMultiplePattern:
- def __init__(self, regex, urlconf_module):
+class RegexURLResolver:
+ def __init__(self, regex, urlconf_name):
+ # regex is a string representing a regular expression.
+ # urlconf_name is a string representing the module containing urlconfs.
self.regex = re.compile(regex)
- # urlconf_module is a string representing the module containing urlconfs.
- self.urlconf_module = urlconf_module
+ self.urlconf_name = urlconf_name
- def search(self, path):
+ def resolve(self, path):
match = self.regex.search(path)
if match:
new_path = path[match.end():]
- try: # Lazily load self.url_patterns.
- self.url_patterns
- except AttributeError:
- self.url_patterns = self.get_url_patterns()
for pattern in self.url_patterns:
- sub_match = pattern.search(new_path)
+ sub_match = pattern.resolve(new_path)
if sub_match:
return sub_match
+ # None of the regexes matched, so raise a 404.
+ raise Http404, "Tried all URL patterns but didn't find a match for %r" % path
- def get_url_patterns(self):
- return __import__(self.urlconf_module, '', '', ['']).urlpatterns
-
-class RegexURLResolver:
- def __init__(self, url_patterns):
- # url_patterns is a list of RegexURLPattern or RegexURLMultiplePattern objects.
- self.url_patterns = url_patterns
+ def _get_urlconf_module(self):
+ self.urlconf_module = __import__(self.urlconf_name, '', '', [''])
+ return self.urlconf_module
+ urlconf_module = property(_get_urlconf_module)
- def resolve(self, app_path):
- # app_path is the full requested Web path. This is assumed to have a
- # leading slash but doesn't necessarily have a trailing slash.
- # Examples:
- # "/news/2005/may/"
- # "/news/"
- # "/polls/latest"
- # A home (root) page is represented by "/".
- app_path = app_path[1:] # Trim leading slash.
- for pattern in self.url_patterns:
- match = pattern.search(app_path)
- if match:
- return match
- # None of the regexes matched, so raise a 404.
- raise Http404, "Tried all URL patterns but didn't find a match for %r" % app_path
+ def _get_url_patterns(self):
+ self.url_patterns = self.urlconf_module.urlpatterns
+ return self.url_patterns
+ url_patterns = property(_get_url_patterns)
-class Error404Resolver:
- def __init__(self, callback):
- self.callback = callback
-
- def resolve(self):
- mod_name, func_name = get_mod_func(self.callback)
+ def _resolve_special(self, view_type):
+ callback = getattr(self.urlconf_module, 'handler%s' % view_type)
+ mod_name, func_name = get_mod_func(callback)
try:
return getattr(__import__(mod_name, '', '', ['']), func_name), {}
except (ImportError, AttributeError), e:
- raise ViewDoesNotExist, "Tried %s. Error was: %s" % (self.callback, str(e))
+ raise ViewDoesNotExist, "Tried %s. Error was: %s" % (callback, str(e))
+
+ def resolve404(self):
+ return self._resolve_special('404')
+
+ def resolve500(self):
+ return self._resolve_special('500')
Please sign in to comment.
Something went wrong with that request. Please try again.