Fixed #878 -- URLconf regex captures no longer have to be named groups. Old URLconfs (with named groups) still work. This is backwards-incompatible if you've defined custom middleware with a process_view function. See http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges

git-svn-id: http://code.djangoproject.com/svn/django/trunk@1470 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2005-11-27 22:08:51 +00:00
parent 8c3b41c3e9
commit cc3660c07d
4 changed files with 20 additions and 11 deletions

View File

@ -62,16 +62,16 @@ class BaseHandler:
resolver = urlresolvers.RegexURLResolver(r'^/', ROOT_URLCONF) resolver = urlresolvers.RegexURLResolver(r'^/', ROOT_URLCONF)
try: try:
callback, param_dict = resolver.resolve(path) callback, callback_args, callback_kwargs = resolver.resolve(path)
# Apply view middleware # Apply view middleware
for middleware_method in self._view_middleware: for middleware_method in self._view_middleware:
response = middleware_method(request, callback, param_dict) response = middleware_method(request, callback, callback_args, callback_kwargs)
if response: if response:
return response return response
try: try:
response = callback(request, **param_dict) response = callback(request, *callback_args, **callback_kwargs)
except Exception, e: except Exception, e:
# If the view raised an exception, run it through exception # If the view raised an exception, run it through exception
# middleware, and if the exception middleware returns a # middleware, and if the exception middleware returns a

View File

@ -4,7 +4,7 @@ This module converts requested URLs to callback view functions.
RegexURLResolver is the main class here. Its resolve() method takes a URL (as RegexURLResolver is the main class here. Its resolve() method takes a URL (as
a string) and returns a tuple in this format: a string) and returns a tuple in this format:
(view_function, dict_of_view_function_args) (view_function, function_args, function_kwargs)
""" """
from django.core.exceptions import Http404, ImproperlyConfigured, ViewDoesNotExist from django.core.exceptions import Http404, ImproperlyConfigured, ViewDoesNotExist
@ -31,12 +31,22 @@ class RegexURLPattern:
def resolve(self, path): def resolve(self, path):
match = self.regex.search(path) match = self.regex.search(path)
if match: if match:
args = dict(match.groupdict(), **self.default_args) # If there are any named groups, use those as kwargs, ignoring
# non-named groups. Otherwise, pass all non-named arguments as
# positional arguments.
kwargs = match.groupdict()
if kwargs:
args = ()
if not kwargs:
args = match.groups()
# In both cases, pass any extra_kwargs as **kwargs.
kwargs.update(self.default_args)
try: # Lazily load self.func. try: # Lazily load self.func.
return self.func, args return self.func, args, kwargs
except AttributeError: except AttributeError:
self.func = self.get_callback() self.func = self.get_callback()
return self.func, args return self.func, args, kwargs
def get_callback(self): def get_callback(self):
mod_name, func_name = get_mod_func(self.callback) mod_name, func_name = get_mod_func(self.callback)
@ -66,7 +76,7 @@ class RegexURLResolver(object):
tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']]) tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']])
else: else:
if sub_match: if sub_match:
return sub_match[0], dict(match.groupdict(), **sub_match[1]) return sub_match[0], sub_match[1], dict(match.groupdict(), **sub_match[2])
tried.append(pattern.regex.pattern) tried.append(pattern.regex.pattern)
raise Resolver404, {'tried': tried, 'path': new_path} raise Resolver404, {'tried': tried, 'path': new_path}

View File

@ -5,8 +5,7 @@ class XViewMiddleware:
""" """
Adds an X-View header to internal HEAD requests -- used by the documentation system. Adds an X-View header to internal HEAD requests -- used by the documentation system.
""" """
def process_view(self, request, view_func, view_args, view_kwargs):
def process_view(self, request, view_func, param_dict):
""" """
If the request method is HEAD and the IP is internal, quickly return If the request method is HEAD and the IP is internal, quickly return
with an x-header indicating the view function. This is used by the with an x-header indicating the view function. This is used by the

View File

@ -13,7 +13,7 @@ def decorator_from_middleware(middleware_class):
if result is not None: if result is not None:
return result return result
if hasattr(middleware, 'process_view'): if hasattr(middleware, 'process_view'):
result = middleware.process_view(request, view_func, **kwargs) result = middleware.process_view(request, view_func, *args, **kwargs)
if result is not None: if result is not None:
return result return result
try: try: