Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

loading.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import sys
  2. import traceback
  3. from imp import new_module
  4. from django.conf import settings
  5. from django.core.exceptions import ImproperlyConfigured
  6. from django.db.models import get_model
  7. class AppNotFoundError(Exception):
  8. pass
  9. class ClassNotFoundError(Exception):
  10. pass
  11. def get_class(module_label, classname):
  12. return get_classes(module_label, [classname])[0]
  13. def get_classes(module_label, classnames):
  14. """
  15. For dynamically importing classes from a module.
  16. Eg. calling get_classes('catalogue.models', ['Product']) will search
  17. INSTALLED_APPS for the relevant product app (default is
  18. 'oscar.apps.catalogue') and then import the classes from there. If the
  19. class can't be found in the overriding module, then we attempt to import it
  20. from within oscar.
  21. This is very similar to django.db.models.get_model although that is only
  22. for loading models while this method will load any class.
  23. """
  24. app_module_path = _get_app_module_path(module_label)
  25. if not app_module_path:
  26. raise AppNotFoundError("No app found matching '%s'" % module_label)
  27. # Check if app is in oscar
  28. if app_module_path.split('.')[0] == 'oscar':
  29. # Using core oscar class
  30. module_path = 'oscar.apps.%s' % module_label
  31. imported_module = __import__(module_path, fromlist=classnames)
  32. return _pluck_classes([imported_module], classnames)
  33. # App must be local - check if module is in local app (it could be in
  34. # oscar's)
  35. app_label = module_label.split('.')[0]
  36. if '.' in app_module_path:
  37. base_package = app_module_path.rsplit('.' + app_label, 1)[0]
  38. local_app = "%s.%s" % (base_package, module_label)
  39. else:
  40. local_app = module_label
  41. try:
  42. imported_local_module = __import__(local_app, fromlist=classnames)
  43. except ImportError:
  44. # There are 2 reasons why there is ImportError:
  45. # 1. local_app does not exist
  46. # 2. local_app exists but is corrupted (ImportError inside of the app)
  47. #
  48. # Obviously, for the reason #1 we want to fail back to use Oscar app.
  49. # For the reason #2 we want to propagate error (the dev obviously wants
  50. # to override app and not use Oscar app)
  51. #
  52. # ImportError does not provide easy way to distinguish those two cases.
  53. # Fortunatelly, the traceback of the ImportError starts at __import__
  54. # statement. If the traceback has more than one frame, it means that
  55. # application was found and ImportError originates within the local app
  56. __, __, exc_traceback = sys.exc_info()
  57. frames = traceback.extract_tb(exc_traceback)
  58. if len(frames) > 1:
  59. raise
  60. # Module not in local app
  61. imported_local_module = {}
  62. oscar_app = "oscar.apps.%s" % module_label
  63. imported_oscar_module = __import__(oscar_app, fromlist=classnames)
  64. return _pluck_classes([imported_local_module, imported_oscar_module],
  65. classnames)
  66. def _pluck_classes(modules, classnames):
  67. klasses = []
  68. for classname in classnames:
  69. klass = None
  70. for module in modules:
  71. if hasattr(module, classname):
  72. klass = getattr(module, classname)
  73. break
  74. if not klass:
  75. packages = [m.__name__ for m in modules]
  76. raise ClassNotFoundError("No class '%s' found in %s" % (
  77. classname, ", ".join(packages)))
  78. klasses.append(klass)
  79. return klasses
  80. def _get_app_module_path(module_label):
  81. app_name = module_label.rsplit(".", 1)[0]
  82. for installed_app in settings.INSTALLED_APPS:
  83. if installed_app.endswith(app_name):
  84. return installed_app
  85. return None
  86. def import_module(module_label, classes, namespace=None):
  87. """
  88. This is the deprecated old way of loading modules
  89. """
  90. klasses = get_classes(module_label, classes)
  91. if namespace:
  92. for classname, klass in zip(classes, klasses):
  93. namespace[classname] = klass
  94. else:
  95. module = new_module("oscar.apps.%s" % module_label)
  96. for classname, klass in zip(classes, klasses):
  97. setattr(module, classname, klass)
  98. return module
  99. def get_profile_class():
  100. """
  101. Return the profile model class
  102. """
  103. setting = getattr(settings, 'AUTH_PROFILE_MODULE', None)
  104. if setting is None:
  105. return None
  106. app_label, model_name = settings.AUTH_PROFILE_MODULE.split('.')
  107. profile_class = get_model(app_label, model_name)
  108. if not profile_class:
  109. raise ImproperlyConfigured("Can't import profile model")
  110. return profile_class
  111. def feature_hidden(feature_name):
  112. """
  113. Test if a certain Oscar feature is disabled.
  114. """
  115. return (feature_name is not None and
  116. feature_name in settings.OSCAR_HIDDEN_FEATURES)