Ticket #13154: django-smarter-reverse.2.patch
File django-smarter-reverse.2.patch, 6.0 KB (added by , 14 years ago) |
---|
-
tests/regressiontests/urlpatterns_reverse/views.py
13 13 def absolute_kwargs_view(request, arg1=1, arg2=2): 14 14 return HttpResponse('') 15 15 16 def defaults_view(request, arg1, arg2): 17 pass 18 16 19 class ViewClass(object): 17 20 def __call__(self, request, *args, **kwargs): 18 21 return HttpResponse('') -
tests/regressiontests/urlpatterns_reverse/tests.py
127 127 ('kwargs_view', '/arg_view/10/', [], {'arg1':10}), 128 128 ('regressiontests.urlpatterns_reverse.views.absolute_kwargs_view', '/absolute_arg_view/', [], {}), 129 129 ('regressiontests.urlpatterns_reverse.views.absolute_kwargs_view', '/absolute_arg_view/10/', [], {'arg1':10}), 130 ('non_path_include', '/includes/non_path_include/', [], {}) 130 ('non_path_include', '/includes/non_path_include/', [], {}), 131 131 132 # Tests for #13154 133 ('defaults', '/defaults_view1/3/', [], {'arg1': 3, 'arg2': 1}), 134 ('defaults', '/defaults_view2/3/', [], {'arg1': 3, 'arg2': 2}), 135 ('defaults', NoReverseMatch, [], {'arg1': 3, 'arg2': 3}), 136 ('defaults', NoReverseMatch, [], {'arg2': 1}), 132 137 ) 133 138 134 139 class NoURLPatternsTests(TestCase): -
tests/regressiontests/urlpatterns_reverse/urls.py
19 19 url(r'^people/(?:name/)', empty_view, name="people2"), 20 20 url(r'^people/(?:name/(\w+)/)?', empty_view, name="people2a"), 21 21 url(r'^optional/(?P<name>.*)/(?:.+/)?', empty_view, name="optional"), 22 url(r'^hardcoded/$', 'hardcoded/',empty_view, name="hardcoded"),22 url(r'^hardcoded/$', empty_view, name="hardcoded"), 23 23 url(r'^hardcoded/doc\.pdf$', empty_view, name="hardcoded2"), 24 24 url(r'^people/(?P<state>\w\w)/(?P<name>\w+)/$', empty_view, name="people3"), 25 25 url(r'^people/(?P<state>\w\w)/(?P<name>\d)/$', empty_view, name="people4"), … … 55 55 url(r'arg_view/(?P<arg1>\d+)/$', 'kwargs_view'), 56 56 url(r'absolute_arg_view/(?P<arg1>\d+)/$', absolute_kwargs_view), 57 57 url(r'absolute_arg_view/$', absolute_kwargs_view), 58 58 59 # Tests for #13154. Mixed syntax to test both ways of defining URLs. 60 url(r'defaults_view1/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 1}, name='defaults'), 61 (r'defaults_view2/(?P<arg1>\d+)/', 'defaults_view', {'arg2': 2}, 'defaults'), 62 59 63 url('^includes/', include(other_patterns)), 60 64 61 65 ) -
django/core/urlresolvers.py
206 206 else: 207 207 parent = normalize(pattern.regex.pattern) 208 208 for name in pattern.reverse_dict: 209 for matches, pat in pattern.reverse_dict.getlist(name):209 for matches, pat, defaults in pattern.reverse_dict.getlist(name): 210 210 new_matches = [] 211 211 for piece, p_args in parent: 212 212 new_matches.extend([(piece + suffix, p_args + args) for (suffix, args) in matches]) 213 lookups.appendlist(name, (new_matches, p_pattern + pat ))213 lookups.appendlist(name, (new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs))) 214 214 for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items(): 215 215 namespaces[namespace] = (p_pattern + prefix, sub_pattern) 216 216 for app_name, namespace_list in pattern.app_dict.items(): 217 217 apps.setdefault(app_name, []).extend(namespace_list) 218 218 else: 219 219 bits = normalize(p_pattern) 220 lookups.appendlist(pattern.callback, (bits, p_pattern ))220 lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args)) 221 221 if pattern.name is not None: 222 lookups.appendlist(pattern.name, (bits, p_pattern ))222 lookups.appendlist(pattern.name, (bits, p_pattern, pattern.default_args)) 223 223 self._reverse_dict = lookups 224 224 self._namespace_dict = namespaces 225 225 self._app_dict = apps … … 310 310 except (ImportError, AttributeError), e: 311 311 raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e)) 312 312 possibilities = self.reverse_dict.getlist(lookup_view) 313 for possibility, pattern in possibilities:313 for possibility, pattern, defaults in possibilities: 314 314 for result, params in possibility: 315 315 if args: 316 316 if len(args) != len(params): … … 318 318 unicode_args = [force_unicode(val) for val in args] 319 319 candidate = result % dict(zip(params, unicode_args)) 320 320 else: 321 if set(kwargs.keys() ) != set(params):321 if set(kwargs.keys() + defaults.keys()) != set(params + defaults.keys()): 322 322 continue 323 matches = True 324 for k, v in defaults.items(): 325 if kwargs.get(k, v) != v: 326 matches = False 327 break 328 if not matches: 329 continue 323 330 unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()]) 324 331 candidate = result % unicode_kwargs 325 332 if re.search(u'^%s' % pattern, candidate, re.UNICODE):