Ticket #3402: django_stem.patch
File django_stem.patch, 11.5 KB (added by , 18 years ago) |
---|
-
django/conf/urls/defaults.py
1 from django.core.urlresolvers import RegexURLPattern, RegexURLResolver 1 from django.core.urlresolvers import RegexURLPattern, RegexURLResolver, Stem 2 2 3 __all__ = ['handler404', 'handler500', 'include', 'patterns' ]3 __all__ = ['handler404', 'handler500', 'include', 'patterns', 'stem'] 4 4 5 5 handler404 = 'django.views.defaults.page_not_found' 6 6 handler500 = 'django.views.defaults.server_error' 7 7 8 stem = Stem() 9 8 10 include = lambda urlconf_module: [urlconf_module] 9 11 10 12 def patterns(prefix, *tuples): -
django/core/handlers/base.py
65 65 66 66 resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) 67 67 try: 68 callback, callback_args, callback_kwargs = resolver.resolve(request.path)68 callback, callback_args, callback_kwargs, stem = resolver.resolve(request.path) 69 69 70 70 # Apply view middleware 71 71 for middleware_method in self._view_middleware: -
django/core/urlresolvers.py
11 11 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist 12 12 import re 13 13 14 class Stem(object): 15 pass 16 14 17 class Resolver404(Http404): 15 18 pass 16 19 17 20 class NoReverseMatch(Exception): 18 21 # Don't make this raise an error when used in a template. 19 silent_variable_failure = True 22 silent_variable_failure = True 20 23 21 24 def get_mod_func(callback): 22 25 # Converts 'django.views.news.stories.story_detail' to … … 101 104 self._callback_str = callback 102 105 self.default_args = default_args or {} 103 106 104 def resolve(self, path): 107 self._stem = None 108 for k,v in self.default_args.iteritems(): 109 if type(v) == Stem: 110 self._stem = k 111 break 112 113 def resolve(self, path, stem=''): 105 114 match = self.regex.search(path) 106 115 if match: 107 116 # If there are any named groups, use those as kwargs, ignoring … … 113 122 if not kwargs: 114 123 args = match.groups() 115 124 # In both cases, pass any extra_kwargs as **kwargs. 125 if self._stem: 126 self.default_args[self._stem] = stem 116 127 kwargs.update(self.default_args) 117 128 118 return self.callback, args, kwargs 129 return self.callback, args, kwargs, stem 119 130 120 131 def _get_callback(self): 121 132 if self._callback is not None: … … 152 163 self.callback = None 153 164 self.default_kwargs = default_kwargs or {} 154 165 155 def resolve(self, path): 166 self._stem = None 167 for k,v in self.default_kwargs.iteritems(): 168 if type(v) == Stem: 169 self._stem = k 170 break 171 172 def resolve(self, path, stem=''): 156 173 tried = [] 157 174 match = self.regex.search(path) 158 175 if match: 176 stem += path[:match.end()] 159 177 new_path = path[match.end():] 160 178 for pattern in self.urlconf_module.urlpatterns: 161 179 try: 162 sub_match = pattern.resolve(new_path )180 sub_match = pattern.resolve(new_path, stem) 163 181 except Resolver404, e: 164 182 tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']]) 165 183 else: 166 184 if sub_match: 185 if self._stem: 186 self.default_kwargs[self._stem] = sub_match[3] 167 187 sub_match_dict = dict(self.default_kwargs, **sub_match[2]) 168 return sub_match[0], sub_match[1], dict(match.groupdict(), **sub_match_dict) 188 return sub_match[0], sub_match[1], dict(match.groupdict(), **sub_match_dict), sub_match[3] 169 189 tried.append(pattern.regex.pattern) 170 190 raise Resolver404, {'tried': tried, 'path': new_path} 171 191 … … 229 249 from django.conf import settings 230 250 urlconf = settings.ROOT_URLCONF 231 251 resolver = RegexURLResolver(r'^/', urlconf) 232 return resolver.resolve(path) 252 return resolver.resolve(path)[:3] 233 253 234 254 def reverse(viewname, urlconf=None, args=None, kwargs=None): 235 255 args = args or [] -
docs/url_dispatch.txt
215 215 A function that takes a full Python import path to another URLconf that should 216 216 be "included" in this place. See _`Including other URLconfs` below. 217 217 218 stem 219 ---- 220 221 ** New in Django development version ** 222 223 An object that you can use in the optional dictionary to pass the part of the 224 url that matched upto the point before matching against patterns in the current 225 URLconf. See _`Including other URLconfs` below. 226 218 227 Notes on capturing text in URLs 219 228 =============================== 220 229 … … 364 373 In the above example, the captured ``"username"`` variable is passed to the 365 374 included URLconf, as expected. 366 375 376 Passing the stem of the matched URL 377 ----------------------------------- 378 379 ** New in Django development version ** 380 381 In the following example:: 382 383 # In settings/urls/main.py 384 urlpatterns = patterns('', 385 (r'^blog/', include('foo.urls.blog')), 386 ) 387 388 # In foo/urls/blog.py 389 urlpatterns = patterns('foo.views', 390 (r'^$', 'blog.index', {'stem':stem}), 391 (r'^archive/$', 'blog.archive', {'stem':stem}), 392 ) 393 394 In the above example, both blog.index and blog.archive will be passed a kwarg 395 called 'stem', and having the value '/blog/' (coming from settings/urls/main.py.) 396 367 397 Passing extra options to view functions 368 398 ======================================= 369 399 -
tests/regressiontests/urlpatterns/urls3.py
1 from django.conf.urls.defaults import * 2 3 urlpatterns = patterns('regressiontests.urlpatterns.tests', 4 (r'^test/$','view'), 5 ) 6 No newline at end of file -
tests/regressiontests/urlpatterns/tests.py
1 "Unit tests for URL lookup" 2 3 from django.conf import settings 4 from django.core.urlresolvers import resolve 5 import unittest 6 7 def view(request): 8 pass 9 10 class URLPattern(unittest.TestCase): 11 def setUp(self): 12 self._url_conf = settings.ROOT_URLCONF 13 settings.ROOT_URLCONF = 'regressiontests.urlpatterns.urls1' 14 15 def tearDown(self): 16 settings.ROOT_URLCONF = self._url_conf 17 18 def test_urlpattern_1(self): 19 result = resolve('/test/') 20 self.assertEqual('stem' in result[2], False) 21 22 def test_urlpattern_2(self): 23 result = resolve('/include/test/') 24 self.assertEqual('stem' in result[2], True) 25 self.assertEqual(result[2]['stem'],'/include/') 26 27 def test_urlpattern_3(self): 28 result = resolve('/include/include/test/') 29 self.assertEqual('stem' in result[2], True) 30 self.assertEqual(result[2]['stem'],'/include/include/') -
tests/regressiontests/urlpatterns/urls1.py
1 from django.conf.urls.defaults import * 2 3 urlpatterns = patterns('regressiontests.urlpatterns.tests', 4 (r'^test/$','view'), 5 (r'^include/',include('regressiontests.urlpatterns.urls2')), 6 ) 7 No newline at end of file -
tests/regressiontests/urlpatterns/urls2.py
1 from django.conf.urls.defaults import * 2 3 urlpatterns = patterns('regressiontests.urlpatterns.tests', 4 (r'^test/$','view',{'stem':stem}), 5 (r'^include/',include('regressiontests.urlpatterns.urls3'),{'stem':stem}), 6 ) 7 No newline at end of file -
tests/regressiontests/urlpatterns/tests.py
1 "Unit tests for URL lookup" 2 3 from django.conf import settings 4 from django.core.urlresolvers import resolve 5 import unittest 6 7 def view(request): 8 pass 9 10 class URLPattern(unittest.TestCase): 11 def setUp(self): 12 self._url_conf = settings.ROOT_URLCONF 13 settings.ROOT_URLCONF = 'regressiontests.urlpatterns.urls1' 14 15 def tearDown(self): 16 settings.ROOT_URLCONF = self._url_conf 17 18 def test_urlpattern_1(self): 19 result = resolve('/test/') 20 self.assertEqual('stem' in result[2], False) 21 22 def test_urlpattern_2(self): 23 result = resolve('/include/test/') 24 self.assertEqual('stem' in result[2], True) 25 self.assertEqual(result[2]['stem'],'/include/') 26 27 def test_urlpattern_3(self): 28 result = resolve('/include/include/test/') 29 self.assertEqual('stem' in result[2], True) 30 self.assertEqual(result[2]['stem'],'/include/include/') -
tests/regressiontests/urlpatterns/urls1.py
1 from django.conf.urls.defaults import * 2 3 urlpatterns = patterns('regressiontests.urlpatterns.tests', 4 (r'^test/$','view'), 5 (r'^include/',include('regressiontests.urlpatterns.urls2')), 6 ) 7 No newline at end of file -
tests/regressiontests/urlpatterns/urls2.py
1 from django.conf.urls.defaults import * 2 3 urlpatterns = patterns('regressiontests.urlpatterns.tests', 4 (r'^test/$','view',{'stem':stem}), 5 (r'^include/',include('regressiontests.urlpatterns.urls3'),{'stem':stem}), 6 ) 7 No newline at end of file -
tests/regressiontests/urlpatterns/urls3.py
1 from django.conf.urls.defaults import * 2 3 urlpatterns = patterns('regressiontests.urlpatterns.tests', 4 (r'^test/$','view'), 5 ) 6 No newline at end of file