from django.core.urlresolvers import RegexURLResolver def extend(root_resolver, extra_parm_dct, require_matches=True): ''' Extend a resolver to have extra parameters passed in by a per-name basis, and also validate that names exist so that child application can essentially validate the API of the app whose urls it is including root_resolver: should be url w/include (see example below) extra_parm_dct: keys: should be names defined for reverse calls values: dictionaries of extra parameters to be sent to views require_matches: if True, raise exception if some names are not found Limitations: 1) only tested on python 2.5, django 1.1 2) modifies resolvers directly, does not clone them Example usage: extend(url(r'', include('member.urls')), { 'make_payment': {'make_payment_form': QuickEnrollPaymentForm}, 'home_page': {}, # simply must exist } ), ''' if not isinstance(root_resolver, RegexURLResolver): raise TypeError('Expected RegexURLResolver argument') names_to_extend = set(extra_parm_dct.keys()) def _extend(resolver): for pattern in resolver.url_patterns: if isinstance(pattern, RegexURLResolver): _extend(pattern) else: name = pattern.name if name in extra_parm_dct: extra_args = extra_parm_dct[name] pattern.default_args.update(extra_args) names_to_extend.discard(name) _extend(root_resolver) if require_matches and len(names_to_extend) > 0: raise Exception('The following names do not exist in extended urlconf: %s' % names_to_extend) return root_resolver