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).
(lookup_view)
| 7 | |
| 8 | @functools.cache |
| 9 | def get_callable(lookup_view): |
| 10 | """ |
| 11 | Return a callable corresponding to lookup_view. |
| 12 | * If lookup_view is already a callable, return it. |
| 13 | * If lookup_view is a string import path that can be resolved to a |
| 14 | callable, import that callable and return it, otherwise raise an |
| 15 | exception (ImportError or ViewDoesNotExist). |
| 16 | """ |
| 17 | if callable(lookup_view): |
| 18 | return lookup_view |
| 19 | |
| 20 | if not isinstance(lookup_view, str): |
| 21 | raise ViewDoesNotExist( |
| 22 | "'%s' is not a callable or a dot-notation path" % lookup_view |
| 23 | ) |
| 24 | |
| 25 | mod_name, func_name = get_mod_func(lookup_view) |
| 26 | if not func_name: # No '.' in lookup_view |
| 27 | raise ImportError( |
| 28 | "Could not import '%s'. The path must be fully qualified." % lookup_view |
| 29 | ) |
| 30 | |
| 31 | try: |
| 32 | mod = import_module(mod_name) |
| 33 | except ImportError: |
| 34 | parentmod, submod = get_mod_func(mod_name) |
| 35 | if submod and not module_has_submodule(import_module(parentmod), submod): |
| 36 | raise ViewDoesNotExist( |
| 37 | "Could not import '%s'. Parent module %s does not exist." |
| 38 | % (lookup_view, mod_name) |
| 39 | ) |
| 40 | else: |
| 41 | raise |
| 42 | else: |
| 43 | try: |
| 44 | view_func = getattr(mod, func_name) |
| 45 | except AttributeError: |
| 46 | raise ViewDoesNotExist( |
| 47 | "Could not import '%s'. View does not exist in module %s." |
| 48 | % (lookup_view, mod_name) |
| 49 | ) |
| 50 | else: |
| 51 | if not callable(view_func): |
| 52 | raise ViewDoesNotExist( |
| 53 | "Could not import '%s.%s'. View is not callable." |
| 54 | % (mod_name, func_name) |
| 55 | ) |
| 56 | return view_func |
| 57 | |
| 58 | |
| 59 | def get_mod_func(callback): |