|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- import functools
- from importlib import import_module
-
- from django.core.exceptions import ViewDoesNotExist
- from django.utils.module_loading import module_has_submodule
-
-
- @functools.lru_cache(maxsize=None)
- def get_callable(lookup_view):
- """
- Return a callable corresponding to lookup_view.
- * If lookup_view is already a callable, return it.
- * If lookup_view is a string import path that can be resolved to a callable,
- import that callable and return it, otherwise raise an exception
- (ImportError or ViewDoesNotExist).
- """
- if callable(lookup_view):
- return lookup_view
-
- if not isinstance(lookup_view, str):
- raise ViewDoesNotExist("'%s' is not a callable or a dot-notation path" % lookup_view)
-
- mod_name, func_name = get_mod_func(lookup_view)
- if not func_name: # No '.' in lookup_view
- raise ImportError("Could not import '%s'. The path must be fully qualified." % lookup_view)
-
- try:
- mod = import_module(mod_name)
- except ImportError:
- parentmod, submod = get_mod_func(mod_name)
- if submod and not module_has_submodule(import_module(parentmod), submod):
- raise ViewDoesNotExist(
- "Could not import '%s'. Parent module %s does not exist." %
- (lookup_view, mod_name)
- )
- else:
- raise
- else:
- try:
- view_func = getattr(mod, func_name)
- except AttributeError:
- raise ViewDoesNotExist(
- "Could not import '%s'. View does not exist in module %s." %
- (lookup_view, mod_name)
- )
- else:
- if not callable(view_func):
- raise ViewDoesNotExist(
- "Could not import '%s.%s'. View is not callable." %
- (mod_name, func_name)
- )
- return view_func
-
-
- def get_mod_func(callback):
- # Convert 'django.views.news.stories.story_detail' to
- # ['django.views.news.stories', 'story_detail']
- try:
- dot = callback.rindex('.')
- except ValueError:
- return callback, ''
- return callback[:dot], callback[dot + 1:]
|