You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

loading.py 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from imp import new_module
  2. from django.conf import settings
  3. from django.core.exceptions import ImproperlyConfigured
  4. from django.db.models import get_model
  5. class AppNotFoundError(Exception):
  6. pass
  7. class ClassNotFoundError(Exception):
  8. pass
  9. def get_class(module_label, classname):
  10. return get_classes(module_label, [classname])[0]
  11. def get_classes(module_label, classnames):
  12. """
  13. For dynamically importing classes from a module.
  14. Eg. calling get_classes('catalogue.models', ['Product']) will search
  15. INSTALLED_APPS for the relevant product app (default is
  16. 'oscar.apps.catalogue') and then import the classes from there. If the
  17. class can't be found in the overriding module, then we attempt to import it
  18. from within oscar.
  19. This is very similar to django.db.models.get_model although that is only
  20. for loading models while this method will load any class.
  21. """
  22. app_module_path = _get_app_module_path(module_label)
  23. if not app_module_path:
  24. raise AppNotFoundError("No app found matching '%s'" % module_label)
  25. # Check if app is in oscar
  26. if app_module_path.split('.')[0] == 'oscar':
  27. # Using core oscar class
  28. module_path = 'oscar.apps.%s' % module_label
  29. imported_module = __import__(module_path, fromlist=classnames)
  30. return _pluck_classes([imported_module], classnames)
  31. # App must be local - check if module is in local app (it could be in
  32. # oscar's)
  33. app_label = module_label.split('.')[0]
  34. base_package = app_module_path.rsplit('.' + app_label, 1)[0]
  35. local_app = "%s.%s" % (base_package, module_label)
  36. try:
  37. imported_local_module = __import__(local_app, fromlist=classnames)
  38. except ImportError:
  39. # Module not in local app
  40. imported_local_module = {}
  41. oscar_app = "oscar.apps.%s" % module_label
  42. imported_oscar_module = __import__(oscar_app, fromlist=classnames)
  43. return _pluck_classes([imported_local_module, imported_oscar_module],
  44. classnames)
  45. def _pluck_classes(modules, classnames):
  46. klasses = []
  47. for classname in classnames:
  48. klass = None
  49. for module in modules:
  50. if hasattr(module, classname):
  51. klass = getattr(module, classname)
  52. break
  53. if not klass:
  54. packages = [m.__name__ for m in modules]
  55. raise ClassNotFoundError("No class '%s' found in %s" % (
  56. classname, ", ".join(packages)))
  57. klasses.append(klass)
  58. return klasses
  59. def _get_app_module_path(module_label):
  60. app_name = module_label.rsplit(".", 1)[0]
  61. for installed_app in settings.INSTALLED_APPS:
  62. if installed_app.endswith(app_name):
  63. return installed_app
  64. return None
  65. def import_module(module_label, classes, namespace=None):
  66. """
  67. This is the deprecated old way of loading modules
  68. """
  69. klasses = get_classes(module_label, classes)
  70. if namespace:
  71. for classname, klass in zip(classes, klasses):
  72. namespace[classname] = klass
  73. else:
  74. module = new_module("oscar.apps.%s" % module_label)
  75. for classname, klass in zip(classes, klasses):
  76. setattr(module, classname, klass)
  77. return module
  78. def get_profile_class():
  79. """
  80. Return the profile model class
  81. """
  82. app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
  83. profile_class = get_model(app_label, model_name)
  84. if not profile_class:
  85. raise ImproperlyConfigured("Can't import profile model")
  86. return profile_class