Fixed #4453 -- Allow dots in URL pattern names (although the string in that case is first tried as an import path and only then falls back to being treated as a pattern).

git-svn-id: http://code.djangoproject.com/svn/django/trunk@5530 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-06-25 04:34:34 +00:00
parent 14161dba6b
commit a5802b35dd
3 changed files with 19 additions and 6 deletions

View File

@ -27,11 +27,24 @@ class NoReverseMatch(Exception):
# Don't make this raise an error when used in a template. # Don't make this raise an error when used in a template.
silent_variable_failure = True 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): if not callable(lookup_view):
mod_name, func_name = get_mod_func(lookup_view) mod_name, func_name = get_mod_func(lookup_view)
try:
if func_name != '': if func_name != '':
lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name) lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name)
except (ImportError, AttributeError):
if not can_fail:
raise
return lookup_view return lookup_view
get_callable = memoize(get_callable, _callable_cache) get_callable = memoize(get_callable, _callable_cache)
@ -248,7 +261,7 @@ class RegexURLResolver(object):
def reverse(self, lookup_view, *args, **kwargs): def reverse(self, lookup_view, *args, **kwargs):
try: try:
lookup_view = get_callable(lookup_view) lookup_view = get_callable(lookup_view, True)
except (ImportError, AttributeError): except (ImportError, AttributeError):
raise NoReverseMatch raise NoReverseMatch
if lookup_view in self.reverse_dict: if lookup_view in self.reverse_dict:

View File

@ -725,7 +725,7 @@ class Templates(unittest.TestCase):
'url01' : ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'), '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/'), '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/'), '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 # Failures
'url-fail01' : ('{% url %}', {}, template.TemplateSyntaxError), 'url-fail01' : ('{% url %}', {}, template.TemplateSyntaxError),

View File

@ -7,5 +7,5 @@ urlpatterns = patterns('',
(r'^$', views.index), (r'^$', views.index),
(r'^client/(\d+)/$', views.client), (r'^client/(\d+)/$', views.client),
(r'^client/(\d+)/(?P<action>[^/]+)/$', views.client_action), (r'^client/(\d+)/(?P<action>[^/]+)/$', views.client_action),
url(r'^named-client/(\d+)/$', views.client, name="named-client"), url(r'^named-client/(\d+)/$', views.client, name="named.client"),
) )