Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #13154 -- Fixed the URL resolver's reverse() to match the behav…

…ior of its resolve() with regard to the default kwargs. Many thanks to patrys.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16177 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit fe96214939b76d1e7389b1c569d833e96e3a5074 1 parent eb24b54
Jannis Leidel authored May 07, 2011
19  django/core/urlresolvers.py
@@ -206,20 +206,20 @@ def _populate(self):
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,7 +310,7 @@ def reverse(self, lookup_view, *args, **kwargs):
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,7 +318,14 @@ def reverse(self, lookup_view, *args, **kwargs):
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
+                        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:
322 329
                         continue
323 330
                     unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
324 331
                     candidate = result % unicode_kwargs
7  tests/regressiontests/urlpatterns_reverse/tests.py
@@ -127,8 +127,13 @@
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):
8  tests/regressiontests/urlpatterns_reverse/urls.py
@@ -19,7 +19,7 @@
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,7 +55,11 @@
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
 )
3  tests/regressiontests/urlpatterns_reverse/views.py
@@ -13,6 +13,9 @@ def kwargs_view(request, arg1=1, arg2=2):
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('')

0 notes on commit fe96214

Please sign in to comment.
Something went wrong with that request. Please try again.