diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py index 6ac406c907..a7c686aec5 100644 --- a/django/core/urlresolvers.py +++ b/django/core/urlresolvers.py @@ -27,11 +27,24 @@ class NoReverseMatch(Exception): # Don't make this raise an error when used in a template. silent_variable_failure = True -def get_callable(lookup_view): +def get_callable(lookup_view, can_fail=False): + """ + Convert a string version of a function name to the callable object. + + If the lookup_view is not an import path, it is assumed to be a URL pattern + label and the original string is returned. + + If can_fail is True, lookup_view might be a URL pattern label, so errors + during the import fail and the string is returned. + """ if not callable(lookup_view): mod_name, func_name = get_mod_func(lookup_view) - if func_name != '': - lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name) + try: + if func_name != '': + lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name) + except (ImportError, AttributeError): + if not can_fail: + raise return lookup_view get_callable = memoize(get_callable, _callable_cache) @@ -248,7 +261,7 @@ class RegexURLResolver(object): def reverse(self, lookup_view, *args, **kwargs): try: - lookup_view = get_callable(lookup_view) + lookup_view = get_callable(lookup_view, True) except (ImportError, AttributeError): raise NoReverseMatch if lookup_view in self.reverse_dict: diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index e983a539ae..8c2389b28a 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -725,7 +725,7 @@ class Templates(unittest.TestCase): 'url01' : ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'), 'url02' : ('{% url regressiontests.templates.views.client_action client.id, action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 'url03' : ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'), - 'url04' : ('{% url named-client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'), + 'url04' : ('{% url named.client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'), # Failures 'url-fail01' : ('{% url %}', {}, template.TemplateSyntaxError), diff --git a/tests/regressiontests/templates/urls.py b/tests/regressiontests/templates/urls.py index eaa9fd5d9f..5fbade5c58 100644 --- a/tests/regressiontests/templates/urls.py +++ b/tests/regressiontests/templates/urls.py @@ -7,5 +7,5 @@ urlpatterns = patterns('', (r'^$', views.index), (r'^client/(\d+)/$', views.client), (r'^client/(\d+)/(?P[^/]+)/$', views.client_action), - url(r'^named-client/(\d+)/$', views.client, name="named-client"), + url(r'^named-client/(\d+)/$', views.client, name="named.client"), )