Ticket #13409: wrap_kwarg_for_url.diff

File wrap_kwarg_for_url.diff, 4.6 KB (added by Charlie DeTar, 14 years ago)

New feature: wrap kwarg for "url" to decorate views.

  • conf/urls/defaults.py

     
    2727        pattern_list.append(t)
    2828    return pattern_list
    2929
    30 def url(regex, view, kwargs=None, name=None, prefix=''):
     30def url(regex, view, kwargs=None, name=None, prefix='', wrap=None):
    3131    if isinstance(view, (list,tuple)):
    3232        # For include(...) processing.
    3333        urlconf_module, app_name, namespace = view
    34         return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
     34        return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace, wrap=wrap)
    3535    else:
    3636        if isinstance(view, basestring):
    3737            if not view:
    3838                raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex)
    3939            if prefix:
    4040                view = prefix + '.' + view
    41         return RegexURLPattern(regex, view, kwargs, name)
     41        return RegexURLPattern(regex, view, kwargs, name, wrap=wrap)
    4242
  • core/urlresolvers.py

     
    8787    return callback[:dot], callback[dot+1:]
    8888
    8989class RegexURLPattern(object):
    90     def __init__(self, regex, callback, default_args=None, name=None):
     90    def __init__(self, regex, callback, default_args=None, name=None, wrap=None):
    9191        # regex is a string representing a regular expression.
    9292        # callback is either a string like 'foo.views.news.stories.story_detail'
    9393        # which represents the path to a module and a view function name, or a
     
    100100            self._callback_str = callback
    101101        self.default_args = default_args or {}
    102102        self.name = name
     103        if isinstance(wrap, (list, tuple)):
     104            self.wrap = wrap
     105        elif wrap:
     106            self.wrap = [wrap]
     107        else:
     108            self.wrap = []
    103109
    104110    def __repr__(self):
    105111        return '<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern)
     
    130136
    131137    def _get_callback(self):
    132138        if self._callback is not None:
    133             return self._callback
     139            return self._decorate(self._callback)
    134140        try:
    135141            self._callback = get_callable(self._callback_str)
    136142        except ImportError, e:
     
    139145        except AttributeError, e:
    140146            mod_name, func_name = get_mod_func(self._callback_str)
    141147            raise ViewDoesNotExist("Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e)))
    142         return self._callback
     148        return self._decorate(self._callback)
    143149    callback = property(_get_callback)
    144150
     151    def _decorate(self, callback):
     152        for decorator in reversed(self.wrap):
     153            callback = decorator(callback)
     154        return callback
     155
    145156class RegexURLResolver(object):
    146     def __init__(self, regex, urlconf_name, default_kwargs=None, app_name=None, namespace=None):
     157    def __init__(self, regex, urlconf_name, default_kwargs=None, app_name=None, namespace=None, wrap=None):
    147158        # regex is a string representing a regular expression.
    148159        # urlconf_name is a string representing the module containing URLconfs.
    149160        self.regex = re.compile(regex, re.UNICODE)
     
    157168        self._reverse_dict = None
    158169        self._namespace_dict = None
    159170        self._app_dict = None
     171        if isinstance(wrap, (tuple, list)):
     172            self.wrap = wrap
     173        elif wrap:
     174            self.wrap = [wrap]
     175        else:
     176            self.wrap = []
    160177
    161178    def __repr__(self):
    162179        return '<%s %s (%s:%s) %s>' % (self.__class__.__name__, self.urlconf_name, self.app_name, self.namespace, self.regex.pattern)
     
    232249                        sub_match_dict.update(self.default_kwargs)
    233250                        for k, v in sub_match[2].iteritems():
    234251                            sub_match_dict[smart_str(k)] = v
    235                         return sub_match[0], sub_match[1], sub_match_dict
     252                        return self._decorate(sub_match[0]), sub_match[1], sub_match_dict
    236253                    tried.append(pattern.regex.pattern)
    237254            raise Resolver404({'tried': tried, 'path': new_path})
    238255        raise Resolver404({'path' : path})
    239256
     257    def _decorate(self, callback):
     258        for decorator in reversed(self.wrap):
     259            callback = decorator(callback)
     260        return callback
     261
    240262    def _get_urlconf_module(self):
    241263        try:
    242264            return self._urlconf_module
Back to Top