Changeset 5516
- Timestamp:
- 06/23/07 00:40:28 (1 year ago)
- Files:
-
- django/trunk/django/core/urlresolvers.py (modified) (6 diffs)
- django/trunk/django/utils/functional.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/core/urlresolvers.py
r5086 r5516 10 10 from django.http import Http404 11 11 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist 12 from django.utils.functional import memoize 12 13 import re 14 15 _resolver_cache = {} # Maps urlconf modules to RegexURLResolver instances. 16 _callable_cache = {} # Maps view and url pattern names to their view functions. 13 17 14 18 class Resolver404(Http404): … … 18 22 # Don't make this raise an error when used in a template. 19 23 silent_variable_failure = True 24 25 def get_callable(lookup_view): 26 if not callable(lookup_view): 27 mod_name, func_name = get_mod_func(lookup_view) 28 if func_name != '': 29 lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name) 30 return lookup_view 31 get_callable = memoize(get_callable, _callable_cache) 32 33 def get_resolver(urlconf): 34 if urlconf is None: 35 from django.conf import settings 36 urlconf = settings.ROOT_URLCONF 37 return RegexURLResolver(r'^/', urlconf) 38 get_resolver = memoize(get_resolver, _resolver_cache) 20 39 21 40 def get_mod_func(callback): … … 130 149 if self._callback is not None: 131 150 return self._callback 132 mod_name, func_name = get_mod_func(self._callback_str) 133 try: 134 self._callback = getattr(__import__(mod_name, {}, {}, ['']), func_name) 151 try: 152 self._callback = get_callable(self._callback_str) 135 153 except ImportError, e: 136 154 raise ViewDoesNotExist, "Could not import %s. Error was: %s" % (mod_name, str(e)) … … 161 179 self.callback = None 162 180 self.default_kwargs = default_kwargs or {} 181 self.reverse_dict = {} 182 183 for pattern in reversed(self.urlconf_module.urlpatterns): 184 if isinstance(pattern, RegexURLResolver): 185 for key, value in pattern.reverse_dict.iteritems(): 186 self.reverse_dict[key] = (pattern,) + value 187 else: 188 self.reverse_dict[pattern.callback] = (pattern,) 189 self.reverse_dict[pattern.name] = (pattern,) 163 190 164 191 def resolve(self, path): … … 210 237 211 238 def reverse(self, lookup_view, *args, **kwargs): 212 if not callable(lookup_view): 213 mod_name, func_name = get_mod_func(lookup_view) 214 try: 215 lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name) 216 except (ImportError, AttributeError): 217 if func_name != '': 218 raise NoReverseMatch 219 for pattern in self.urlconf_module.urlpatterns: 220 if isinstance(pattern, RegexURLResolver): 221 try: 222 return pattern.reverse_helper(lookup_view, *args, **kwargs) 223 except NoReverseMatch: 224 continue 225 elif pattern.callback == lookup_view or pattern.name == lookup_view: 226 try: 227 return pattern.reverse_helper(*args, **kwargs) 228 except NoReverseMatch: 229 continue 239 try: 240 lookup_view = get_callable(lookup_view) 241 except (ImportError, AttributeError): 242 raise NoReverseMatch 243 if lookup_view in self.reverse_dict: 244 return ''.join([reverse_helper(part.regex, *args, **kwargs) for part in self.reverse_dict[lookup_view]]) 230 245 raise NoReverseMatch 231 246 … … 236 251 237 252 def resolve(path, urlconf=None): 238 if urlconf is None: 239 from django.conf import settings 240 urlconf = settings.ROOT_URLCONF 241 resolver = RegexURLResolver(r'^/', urlconf) 242 return resolver.resolve(path) 253 return get_resolver(urlconf).resolve(path) 243 254 244 255 def reverse(viewname, urlconf=None, args=None, kwargs=None): 245 256 args = args or [] 246 257 kwargs = kwargs or {} 247 if urlconf is None: 248 from django.conf import settings 249 urlconf = settings.ROOT_URLCONF 250 resolver = RegexURLResolver(r'^/', urlconf) 251 return '/' + resolver.reverse(viewname, *args, **kwargs) 258 return '/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs) 259 django/trunk/django/utils/functional.py
r5091 r5516 3 3 return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)) 4 4 return _curried 5 6 def memoize(func, cache): 7 """ 8 Wrap a function so that results for any argument tuple are stored in 9 'cache'. Note that the args to the function must be usable as dictionary 10 keys. 11 """ 12 def wrapper(*args): 13 if args in cache: 14 return cache[args] 15 16 result = func(*args) 17 cache[args] = result 18 return result 19 return wrapper 5 20 6 21 class Promise:
