def _find_installed_apps_entry(module_label): """ Given a module label, finds the best matching INSTALLED_APPS entry. This is made trickier by the fact that we don't know what part of the module_label is part of the INSTALLED_APPS entry. So we try all possible combinations, trying the longer versions first. E.g. for 'dashboard.catalogue.forms', 'dashboard.catalogue' is attempted before 'dashboard' 给定模块标签,找到最匹配的INSTALLED_APPS条目。 由于我们不知道module_label的哪个部分是INSTALLED_APPS条目的一部分,所以这 变得更加棘手。 所以我们尝试所有可能的组合,首先尝试更长的版本。 例如。 对 于“dashboard.catalogue.forms”,在“仪表板”之前尝试“dashboard.catalogue” """ modules = module_label.split('.') # if module_label is 'dashboard.catalogue.forms.widgets', combinations # will be ['dashboard.catalogue.forms', 'dashboard.catalogue', 'dashboard'] # 如果module_label是'dashboard.catalogue.forms.widgets',则组合将 # 是['dashboard.catalogue.forms','dashboard.catalogue','dashboard'] combinations = [ '.'.join(modules[:-count]) for count in range(1, len(modules))] for app_name in combinations: entry = _get_installed_apps_entry(app_name) if entry: return entry, app_name raise AppNotFoundError( "Couldn't find an app to import %s from" % module_label)
def _find_registered_app_name(module_label): """ Given a module label, finds the name of the matching Oscar app from the Django app registry. """ from oscar.core.application import OscarConfig app_label = module_label.split('.')[0] try: app_config = apps.get_app_config(app_label) except LookupError: raise AppNotFoundError( "Couldn't find an app to import %s from" % module_label) if not isinstance(app_config, OscarConfig): raise AppNotFoundError( "Couldn't find an Oscar app to import %s from" % module_label) return app_config.name
def _get_installed_apps_entry(app_name): """ Walk through INSTALLED_APPS and return the first match. This does depend on the order of INSTALLED_APPS and will break if e.g. 'dashboard.catalogue' comes before 'catalogue' in INSTALLED_APPS. """ for installed_app in settings.INSTALLED_APPS: if installed_app.endswith(app_name): return installed_app raise AppNotFoundError("No app found matching '%s'" % app_name)
def get_app_config_class(module_name): apps_module_name = module_name.rpartition('.')[0] + '.apps' if apps_module_name in sys.modules: oscar_dashboard_config_classes = [] apps_module_classes = inspect.getmembers(sys.modules[apps_module_name], inspect.isclass) for klass in OrderedDict(apps_module_classes).values(): if issubclass(klass, OscarDashboardConfig): oscar_dashboard_config_classes.append(klass) if oscar_dashboard_config_classes: return oscar_dashboard_config_classes[-1] raise AppNotFoundError("Couldn't find an app to import %s from" % module_name)
def _find_installed_apps_entry(module_label): """ Given a module label, finds the best matching INSTALLED_APPS entry. This is made trickier by the fact that we don't know what part of the module_label is part of the INSTALLED_APPS entry. So we try all possible combinations, trying the longer versions first. E.g. for 'dashboard.catalogue.forms', 'dashboard.catalogue' is attempted before 'dashboard' """ modules = module_label.split('.') # if module_label is 'dashboard.catalogue.forms.widgets', combinations # will be ['dashboard.catalogue.forms', 'dashboard.catalogue', 'dashboard'] combinations = [ '.'.join(modules[:-count]) for count in range(1, len(modules))] for app_name in combinations: entry = _get_installed_apps_entry(app_name) if entry: return entry, app_name raise AppNotFoundError( "Couldn't find an app to import %s from" % module_label)
def default_access_fn(user, url_name, url_args=None, url_kwargs=None): # noqa C901 too complex """ Given a url_name and a user, this function tries to assess whether the user has the right to access the URL. The application instance of the view is fetched via the Django app registry. Once the permissions for the view are known, the access logic used by the dashboard decorator is evaluated This function might seem costly, but a simple comparison with DTT did not show any change in response time """ if url_name is None: # it's a heading return True # get view module string. try: url = reverse(url_name, args=url_args, kwargs=url_kwargs) except NoReverseMatch: # In Oscar 1.5 this exception was silently ignored which made debugging # very difficult. Now it is being logged and in future the exception will # be propagated. logger.exception('Invalid URL name {}'.format(url_name)) return False view_module = resolve(url).func.__module__ # We can't assume that the view has the same parent module as the app # config, as either the app config or view can be customised. So we first # look it up in the app registry using "get_containing_app_config", and if # it isn't found, then we walk up the package tree, looking for an # OscarDashboardConfig class, from which we get an app label, and use that # to look it up again in the app registry using "get_app_config". app_config_instance = apps.get_containing_app_config(view_module) if app_config_instance is None: try: app_config_class = get_app_config_class(view_module) except AppNotFoundError: raise ImproperlyConfigured( "Please provide an OscarDashboardConfig subclass in the apps " "module or set a custom access_fn") if hasattr(app_config_class, 'label'): app_label = app_config_class.label else: app_label = app_config_class.name.rpartition('.')[2] try: app_config_instance = apps.get_app_config(app_label) except LookupError: raise AppNotFoundError("Couldn't find an app with the label %s" % app_label) if not isinstance(app_config_instance, OscarDashboardConfig): raise AppNotFoundError( "Couldn't find an Oscar Dashboard app with the label %s" % app_label) # handle name-spaced view names if ':' in url_name: view_name = url_name.split(':')[1] else: view_name = url_name permissions = app_config_instance.get_permissions(view_name) return check_permissions(user, permissions)