diff --git a/AUTHORS b/AUTHORS index 6b539e8b6b..f44bc42af0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -70,6 +70,7 @@ answer newbie questions, and generally made Django that much better: Clint Ecker gandalf@owca.info Baishampayan Ghose + martin.glueck@gmail.com Espen Grindhaug Brant Harris hipertracker@gmail.com diff --git a/django/conf/urls/defaults.py b/django/conf/urls/defaults.py index 07611c5147..17fe603d96 100644 --- a/django/conf/urls/defaults.py +++ b/django/conf/urls/defaults.py @@ -10,8 +10,10 @@ include = lambda urlconf_module: [urlconf_module] def patterns(prefix, *tuples): pattern_list = [] for t in tuples: - if type(t[1]) == list: - pattern_list.append(RegexURLResolver(t[0], t[1][0])) + regex, view_or_include = t[:2] + default_kwargs = t[2:] + if type(view_or_include) == list: + pattern_list.append(RegexURLResolver(regex, view_or_include[0], *default_kwargs)) else: - pattern_list.append(RegexURLPattern(t[0], prefix and (prefix + '.' + t[1]) or t[1], *t[2:])) + pattern_list.append(RegexURLPattern(regex, prefix and (prefix + '.' + view_or_include) or view_or_include, *default_kwargs)) return pattern_list diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py index f4817dd4c9..1da25c9f83 100644 --- a/django/core/urlresolvers.py +++ b/django/core/urlresolvers.py @@ -130,12 +130,13 @@ class RegexURLPattern(object): return reverse_helper(self.regex, *args, **kwargs) class RegexURLResolver(object): - def __init__(self, regex, urlconf_name): + def __init__(self, regex, urlconf_name, default_kwargs=None): # regex is a string representing a regular expression. # urlconf_name is a string representing the module containing urlconfs. self.regex = re.compile(regex) self.urlconf_name = urlconf_name self.callback = None + self.default_kwargs = default_kwargs or {} def resolve(self, path): tried = [] @@ -149,7 +150,8 @@ class RegexURLResolver(object): tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']]) else: if sub_match: - return sub_match[0], sub_match[1], dict(match.groupdict(), **sub_match[2]) + sub_match_dict = dict(self.default_kwargs, **sub_match[2]) + return sub_match[0], sub_match[1], dict(match.groupdict(), **sub_match_dict) tried.append(pattern.regex.pattern) raise Resolver404, {'tried': tried, 'path': new_path} diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt index bc451ca628..6158014fc8 100644 --- a/docs/url_dispatch.txt +++ b/docs/url_dispatch.txt @@ -389,3 +389,45 @@ to pass metadata and options to views. .. _generic views: http://www.djangoproject.com/documentation/generic_views/ .. _syndication framework: http://www.djangoproject.com/documentation/syndication/ + +Passing extra options to ``include()`` +-------------------------------------- + +**New in the Django development version.** + +Similarly, you can pass extra options to ``include()``. When you pass extra +options to ``include()``, *each* line in the included URLconf will be passed +the extra options. + +For example, these two URLconf sets are functionally identical: + +Set one:: + + # main.py + urlpatterns = patterns('', + (r'^blog/', include('inner'), {'blogid': 3}), + ) + + # inner.py + urlpatterns = patterns('', + (r'^archive/$', 'mysite.views.archive'), + (r'^about/$', 'mysite.views.about'), + ) + +Set two:: + + # main.py + urlpatterns = patterns('', + (r'^blog/', include('inner')), + ) + + # inner.py + urlpatterns = patterns('', + (r'^archive/$', 'mysite.views.archive', {'blogid': 3}), + (r'^about/$', 'mysite.views.about', {'blogid': 3}), + ) + +Note that extra options will *always* be passed to *every* line in the included +URLconf, regardless of whether the line's view actually accepts those options +as valid. For this reason, this technique is only useful if you're certain that +every view in the the included URLconf accepts the extra options you're passing.