Commit 5ba743e2 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Made it possible to create apps without a models module.

This commit reverts f44c4a5d and 39bbd165.

django.test.simple will be updated in a separate commit as it requires
invasive changes.
parent 69039bec
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@ class AppConfig(object):
        self.app_module = app_module

        # Module containing models eg. <module 'django.contrib.admin.models'
        # from 'django/contrib/admin/models.pyc'>.
        # from 'django/contrib/admin/models.pyc'>. None if the application
        # doesn't have a models module.
        self.models_module = models_module

        # Mapping of lower case model names to model classes.
+20 −8
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ class BaseAppCache(object):
            for app_name in settings.INSTALLED_APPS:
                if app_name in self.handled:
                    continue
                self.load_app(app_name, True)
                self.load_app(app_name, can_postpone=True)
            if not self.nesting_level:
                for app_name in self.postponed:
                    self.load_app(app_name)
@@ -115,10 +115,10 @@ class BaseAppCache(object):
            models_module = import_module('%s.%s' % (app_name, MODELS_MODULE_NAME))
        except ImportError:
            self.nesting_level -= 1
            # If the app doesn't have a models module, we can just ignore the
            # ImportError and return no models for it.
            # If the app doesn't have a models module, we can just swallow the
            # ImportError and return no models for this app.
            if not module_has_submodule(app_module, MODELS_MODULE_NAME):
                return None
                models_module = None
            # But if the app does have a models module, we need to figure out
            # whether to suppress or propagate the error. If can_postpone is
            # True then it may be that the package is still being imported by
@@ -129,7 +129,7 @@ class BaseAppCache(object):
            else:
                if can_postpone:
                    self.postponed.append(app_name)
                    return None
                    return
                else:
                    raise

@@ -154,22 +154,27 @@ class BaseAppCache(object):
        """
        return self.loaded

    def get_app_configs(self, only_installed=True):
    def get_app_configs(self, only_installed=True, only_with_models_module=False):
        """
        Return an iterable of application configurations.

        If only_installed is True (default), only applications explicitly
        listed in INSTALLED_APPS are considered.

        If only_with_models_module in True (non-default), only applications
        containing a models module are considered.
        """
        self.populate()
        for app_config in self.app_configs.values():
            if only_installed and not app_config.installed:
                continue
            if only_with_models_module and app_config.models_module is None:
                continue
            if self.available_apps is not None and app_config.name not in self.available_apps:
                continue
            yield app_config

    def get_app_config(self, app_label, only_installed=True):
    def get_app_config(self, app_label, only_installed=True, only_with_models_module=False):
        """
        Returns the application configuration for the given app_label.

@@ -180,11 +185,18 @@ class BaseAppCache(object):

        If only_installed is True (default), only applications explicitly
        listed in INSTALLED_APPS are considered.

        If only_with_models_module in True (non-default), only applications
        containing a models module are considered.
        """
        self.populate()
        app_config = self.app_configs.get(app_label)
        if app_config is None or (only_installed and not app_config.installed):
        if app_config is None:
            raise LookupError("No app with label %r." % app_label)
        if only_installed and not app_config.installed:
            raise LookupError("App with label %r isn't in INSTALLED_APPS." % app_label)
        if only_with_models_module and app_config.models_module is None:
            raise LookupError("App with label %r doesn't have a models module." % app_label)
        if self.available_apps is not None and app_config.name not in self.available_apps:
            raise UnavailableApp("App with label %r isn't available." % app_label)
        return app_config
+1 −1
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ If you're unsure, answer 'no'.


def update_all_contenttypes(verbosity=2, **kwargs):
    for app_config in app_cache.get_app_configs():
    for app_config in app_cache.get_app_configs(only_with_models_module=True):
        update_contenttypes(app_config.models_module, None, verbosity, **kwargs)

signals.post_migrate.connect(update_contenttypes)
+7 −3
Original line number Diff line number Diff line
@@ -345,12 +345,16 @@ class AppCommand(BaseCommand):
        if not app_labels:
            raise CommandError('Enter at least one appname.')
        try:
            app_list = [app_cache.get_app_config(app_label).models_module for app_label in app_labels]
            app_configs = [app_cache.get_app_config(app_label) for app_label in app_labels]
        except (LookupError, ImportError) as e:
            raise CommandError("%s. Are you sure your INSTALLED_APPS setting is correct?" % e)
        output = []
        for app in app_list:
            app_output = self.handle_app(app, **options)
        for app_config in app_configs:
            if app_config.models_module is None:
                raise CommandError(
                    "AppCommand cannot handle app %r because it doesn't have "
                    "a models module." % app_config.label)
            app_output = self.handle_app(app_config.models_module, **options)
            if app_output:
                output.append(app_output)
        return '\n'.join(output)
+5 −4
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ class Command(BaseCommand):
            else:
                try:
                    app_obj = app_cache.get_app_config(exclude).models_module
                    if app_obj is not None:
                        excluded_apps.add(app_obj)
                except LookupError:
                    raise CommandError('Unknown app in excludes: %s' % exclude)
@@ -78,7 +79,7 @@ class Command(BaseCommand):
            if primary_keys:
                raise CommandError("You can only use --pks option with one model")
            app_list = OrderedDict((app_config.models_module, None)
                for app_config in app_cache.get_app_configs()
                for app_config in app_cache.get_app_configs(only_with_models_module=True)
                if app_config.models_module not in excluded_apps)
        else:
            if len(app_labels) > 1 and primary_keys:
@@ -91,7 +92,7 @@ class Command(BaseCommand):
                        app = app_cache.get_app_config(app_label).models_module
                    except LookupError:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app in excluded_apps:
                    if app is None or app in excluded_apps:
                        continue
                    model = app_cache.get_model(app_label, model_label)
                    if model is None:
@@ -111,7 +112,7 @@ class Command(BaseCommand):
                        app = app_cache.get_app_config(app_label).models_module
                    except LookupError:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app in excluded_apps:
                    if app is None or app in excluded_apps:
                        continue
                    app_list[app] = None

Loading