diff -r f7582637764c django/core/urlresolvers.py
|
a
|
b
|
|
| 17 | 17 | from django.utils.encoding import iri_to_uri, force_unicode, smart_str |
| 18 | 18 | from django.utils.functional import memoize, lazy |
| 19 | 19 | from django.utils.importlib import import_module |
| | 20 | from django.utils.module_loading import module_has_submodule |
| 20 | 21 | from django.utils.regex_helper import normalize |
| 21 | 22 | |
| 22 | 23 | _resolver_cache = {} # Maps URLconf modules to RegexURLResolver instances. |
| … |
… |
|
| 83 | 84 | during the import fail and the string is returned. |
| 84 | 85 | """ |
| 85 | 86 | if not callable(lookup_view): |
| | 87 | mod_name, func_name = get_mod_func(lookup_view) |
| 86 | 88 | try: |
| 87 | | # Bail early for non-ASCII strings (they can't be functions). |
| 88 | | lookup_view = lookup_view.encode('ascii') |
| 89 | | mod_name, func_name = get_mod_func(lookup_view) |
| 90 | 89 | if func_name != '': |
| 91 | 90 | lookup_view = getattr(import_module(mod_name), func_name) |
| 92 | 91 | if not callable(lookup_view): |
| 93 | | raise AttributeError("'%s.%s' is not a callable." % (mod_name, func_name)) |
| 94 | | except (ImportError, AttributeError): |
| | 92 | raise ViewDoesNotExist("Could not import %s.%s. View is not callable." % (mod_name, func_name)) |
| | 93 | except AttributeError: |
| | 94 | if not can_fail: |
| | 95 | raise ViewDoesNotExist("Could not import %s. View does not exist in module %s." % (lookup_view, mod_name)) |
| | 96 | except ImportError: |
| | 97 | ownermod, submod = get_mod_func(mod_name) |
| | 98 | if not can_fail and submod != '' and not module_has_submodule(import_module(ownermod), submod): |
| | 99 | raise ViewDoesNotExist("Could not import %s. Owning module %s does not exist." % (lookup_view, mod_name)) |
| 95 | 100 | if not can_fail: |
| 96 | 101 | raise |
| 97 | | except UnicodeEncodeError: |
| 98 | | pass |
| 99 | 102 | return lookup_view |
| 100 | 103 | get_callable = memoize(get_callable, _callable_cache, 1) |
| 101 | 104 | |
| … |
… |
|
| 160 | 163 | def _get_callback(self): |
| 161 | 164 | if self._callback is not None: |
| 162 | 165 | return self._callback |
| 163 | | try: |
| 164 | | self._callback = get_callable(self._callback_str) |
| 165 | | except ImportError, e: |
| 166 | | mod_name, _ = get_mod_func(self._callback_str) |
| 167 | | raise ViewDoesNotExist("Could not import %s. Error was: %s" % (mod_name, str(e))) |
| 168 | | except AttributeError, e: |
| 169 | | mod_name, func_name = get_mod_func(self._callback_str) |
| 170 | | raise ViewDoesNotExist("Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))) |
| | 166 | |
| | 167 | self._callback = get_callable(self._callback_str) |
| 171 | 168 | return self._callback |
| 172 | 169 | callback = property(_get_callback) |
| 173 | 170 | |
| … |
… |
|
| 291 | 288 | # Lazy import, since urls.defaults imports this file |
| 292 | 289 | from django.conf.urls import defaults |
| 293 | 290 | callback = getattr(defaults, 'handler%s' % view_type) |
| 294 | | try: |
| 295 | | return get_callable(callback), {} |
| 296 | | except (ImportError, AttributeError), e: |
| 297 | | raise ViewDoesNotExist("Tried %s. Error was: %s" % (callback, str(e))) |
| | 291 | return get_callable(callback), {} |
| 298 | 292 | |
| 299 | 293 | def resolve404(self): |
| 300 | 294 | return self._resolve_special('404') |
diff -r f7582637764c tests/regressiontests/urlpatterns_reverse/tests.py
|
a
|
b
|
|
| 2 | 2 | Unit tests for reverse URL lookups. |
| 3 | 3 | """ |
| 4 | 4 | from django.conf import settings |
| 5 | | from django.core.exceptions import ImproperlyConfigured |
| | 5 | from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist |
| 6 | 6 | from django.core.urlresolvers import reverse, resolve, NoReverseMatch,\ |
| 7 | 7 | Resolver404, ResolverMatch,\ |
| 8 | 8 | RegexURLResolver, RegexURLPattern |
| … |
… |
|
| 470 | 470 | self.assertEqual(match[0], func) |
| 471 | 471 | self.assertEqual(match[1], args) |
| 472 | 472 | self.assertEqual(match[2], kwargs) |
| | 473 | |
| | 474 | class ErroneousViewTests(TestCase): |
| | 475 | urls = 'regressiontests.urlpatterns_reverse.erroneous_urls' |
| | 476 | |
| | 477 | def test_erroneous_resolve(self): |
| | 478 | self.assertRaises(ImportError, self.client.get, '/erroneous_inner/') |
| | 479 | self.assertRaises(ImportError, self.client.get, '/erroneous_outer/') |
| | 480 | self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_inner/') |
| | 481 | self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_outer/') |
| | 482 | self.assertRaises(ViewDoesNotExist, self.client.get, '/uncallable/') |
| | 483 | |
diff -r f7582637764c tests/regressiontests/urlpatterns_reverse/views.py
|
a
|
b
|
|
| 16 | 16 | def defaults_view(request, arg1, arg2): |
| 17 | 17 | pass |
| 18 | 18 | |
| | 19 | def erroneous_view(request): |
| | 20 | import non_existent |
| | 21 | |
| | 22 | uncallable = "Can I be a view? Pleeeease?" |
| | 23 | |
| 19 | 24 | class ViewClass(object): |
| 20 | 25 | def __call__(self, request, *args, **kwargs): |
| 21 | 26 | return HttpResponse('') |