Fixed #24707 -- Improved error reporting for explicitly imported uncallable views
This commit is contained in:
parent
86aaffa5a3
commit
40768ec29d
|
@ -94,6 +94,11 @@ def get_callable(lookup_view, can_fail=False):
|
||||||
if callable(lookup_view):
|
if callable(lookup_view):
|
||||||
return lookup_view
|
return lookup_view
|
||||||
|
|
||||||
|
if not isinstance(lookup_view, six.string_types):
|
||||||
|
raise ViewDoesNotExist(
|
||||||
|
"'%s' is not a callable or a dot-notation path" % lookup_view
|
||||||
|
)
|
||||||
|
|
||||||
mod_name, func_name = get_mod_func(lookup_view)
|
mod_name, func_name = get_mod_func(lookup_view)
|
||||||
if not func_name: # No '.' in lookup_view
|
if not func_name: # No '.' in lookup_view
|
||||||
if can_fail:
|
if can_fail:
|
||||||
|
|
|
@ -19,8 +19,10 @@ with warnings.catch_warnings():
|
||||||
url(r'erroneous_unqualified/$', 'unqualified_view'),
|
url(r'erroneous_unqualified/$', 'unqualified_view'),
|
||||||
# View does not exist
|
# View does not exist
|
||||||
url(r'missing_inner/$', 'urlpatterns_reverse.views.missing_view'),
|
url(r'missing_inner/$', 'urlpatterns_reverse.views.missing_view'),
|
||||||
# View is not callable
|
# View is not a callable (string import; arbitrary Python object)
|
||||||
url(r'uncallable/$', 'urlpatterns_reverse.views.uncallable'),
|
url(r'uncallable-dotted/$', 'urlpatterns_reverse.views.uncallable'),
|
||||||
|
# View is not a callable (explicit import; arbitrary Python object)
|
||||||
|
url(r'uncallable-object/$', views.uncallable),
|
||||||
# Module does not exist
|
# Module does not exist
|
||||||
url(r'missing_outer/$', 'urlpatterns_reverse.missing_module.missing_view'),
|
url(r'missing_outer/$', 'urlpatterns_reverse.missing_module.missing_view'),
|
||||||
# Regex contains an error (refs #6170)
|
# Regex contains an error (refs #6170)
|
||||||
|
|
|
@ -762,7 +762,8 @@ class ErroneousViewTests(TestCase):
|
||||||
self.assertRaises(ImportError, self.client.get, '/erroneous_outer/')
|
self.assertRaises(ImportError, self.client.get, '/erroneous_outer/')
|
||||||
self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_inner/')
|
self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_inner/')
|
||||||
self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_outer/')
|
self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_outer/')
|
||||||
self.assertRaises(ViewDoesNotExist, self.client.get, '/uncallable/')
|
self.assertRaises(ViewDoesNotExist, self.client.get, '/uncallable-dotted/')
|
||||||
|
self.assertRaises(ViewDoesNotExist, self.client.get, '/uncallable-object/')
|
||||||
|
|
||||||
# Regression test for #21157
|
# Regression test for #21157
|
||||||
self.assertRaises(ImportError, self.client.get, '/erroneous_unqualified/')
|
self.assertRaises(ImportError, self.client.get, '/erroneous_unqualified/')
|
||||||
|
|
|
@ -35,7 +35,7 @@ def pass_resolver_match_view(request, *args, **kwargs):
|
||||||
response.resolver_match = request.resolver_match
|
response.resolver_match = request.resolver_match
|
||||||
return response
|
return response
|
||||||
|
|
||||||
uncallable = "Can I be a view? Pleeeease?"
|
uncallable = None # neither a callable nor a string
|
||||||
|
|
||||||
|
|
||||||
class ViewClass(object):
|
class ViewClass(object):
|
||||||
|
|
Loading…
Reference in New Issue