Changeset 3554
- Timestamp:
- 08/11/06 02:01:29 (3 years ago)
- Files:
-
- django/trunk/django/core/urlresolvers.py (modified) (4 diffs)
- django/trunk/docs/url_dispatch.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/core/urlresolvers.py
r3506 r3554 87 87 def __init__(self, regex, callback, default_args=None): 88 88 # regex is a string representing a regular expression. 89 # callback is something like 'foo.views.news.stories.story_detail', 90 # which represents the path to a module and a view function name. 89 # callback is either a string like 'foo.views.news.stories.story_detail' 90 # which represents the path to a module and a view function name, or a 91 # callable object (view). 91 92 self.regex = re.compile(regex) 92 self.callback = callback 93 if callable(callback): 94 self._callback = callback 95 else: 96 self._callback = None 97 self._callback_str = callback 93 98 self.default_args = default_args or {} 94 99 … … 107 112 kwargs.update(self.default_args) 108 113 109 try: # Lazily load self.func. 110 return self.func, args, kwargs 111 except AttributeError: 112 self.func = self.get_callback() 113 return self.func, args, kwargs 114 115 def get_callback(self): 116 mod_name, func_name = get_mod_func(self.callback) 117 try: 118 return getattr(__import__(mod_name, '', '', ['']), func_name) 114 return self.callback, args, kwargs 115 116 def _get_callback(self): 117 if self._callback is not None: 118 return self._callback 119 mod_name, func_name = get_mod_func(self._callback_str) 120 try: 121 self._callback = getattr(__import__(mod_name, '', '', ['']), func_name) 119 122 except ImportError, e: 120 123 raise ViewDoesNotExist, "Could not import %s. Error was: %s" % (mod_name, str(e)) 121 124 except AttributeError, e: 122 125 raise ViewDoesNotExist, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e)) 126 return self._callback 127 callback = property(_get_callback) 123 128 124 129 def reverse(self, viewname, *args, **kwargs): 125 if viewname != self.callback: 130 mod_name, func_name = get_mod_func(viewname) 131 try: 132 lookup_view = getattr(__import__(mod_name, '', '', ['']), func_name) 133 except (ImportError, AttributeError): 134 raise NoReverseMatch 135 if lookup_view != self.callback: 126 136 raise NoReverseMatch 127 137 return self.reverse_helper(*args, **kwargs) … … 186 196 return self._resolve_special('500') 187 197 188 def reverse(self, viewname, *args, **kwargs): 198 def reverse(self, lookup_view, *args, **kwargs): 199 if not callable(lookup_view): 200 mod_name, func_name = get_mod_func(lookup_view) 201 try: 202 lookup_view = getattr(__import__(mod_name, '', '', ['']), func_name) 203 except (ImportError, AttributeError): 204 raise NoReverseMatch 189 205 for pattern in self.urlconf_module.urlpatterns: 190 206 if isinstance(pattern, RegexURLResolver): 191 207 try: 192 return pattern.reverse_helper( viewname, *args, **kwargs)208 return pattern.reverse_helper(lookup_view, *args, **kwargs) 193 209 except NoReverseMatch: 194 210 continue 195 elif pattern.callback == viewname:211 elif pattern.callback == lookup_view: 196 212 try: 197 213 return pattern.reverse_helper(*args, **kwargs) … … 200 216 raise NoReverseMatch 201 217 202 def reverse_helper(self, viewname, *args, **kwargs):203 sub_match = self.reverse( viewname, *args, **kwargs)218 def reverse_helper(self, lookup_view, *args, **kwargs): 219 sub_match = self.reverse(lookup_view, *args, **kwargs) 204 220 result = reverse_helper(self.regex, *args, **kwargs) 205 221 return result + sub_match django/trunk/docs/url_dispatch.txt
r3506 r3554 432 432 as valid. For this reason, this technique is only useful if you're certain that 433 433 every view in the the included URLconf accepts the extra options you're passing. 434 435 Passing callable objects instead of strings 436 =========================================== 437 438 **New in the Django development version.** 439 440 Some developers find it more natural to pass the actual Python function object 441 rather than a string containing the path to its module. This alternative is 442 supported -- you can pass any callable object as the view. 443 444 For example, given this URLconf in "string" notation:: 445 446 urlpatterns = patterns('', 447 (r'^archive/$', 'mysite.views.archive'), 448 (r'^about/$', 'mysite.views.about'), 449 (r'^contact/$', 'mysite.views.contact'), 450 ) 451 452 You can accomplish the same thing by passing objects rather than strings. Just 453 be sure to import the objects:: 454 455 from mysite.views import archive, about, contact 456 457 urlpatterns = patterns('', 458 (r'^archive/$', archive), 459 (r'^about/$', about), 460 (r'^contact/$', contact), 461 ) 462 463 The following example is functionally identical. It's just a bit more compact 464 because it imports the module that contains the views, rather than importing 465 each view individually:: 466 467 from mysite import views 468 469 urlpatterns = patterns('', 470 (r'^archive/$', views.archive), 471 (r'^about/$', views.about), 472 (r'^contact/$', views.contact), 473 ) 474 475 The style you use is up to you. 476 477 Note that if you use this technique -- passing objects rather than strings -- 478 the view prefix (as explained in "The view prefix" above) will have no effect.
