diff --git a/django/apps/base.py b/django/apps/base.py index 31d75bf5ed..784c460bcd 100644 --- a/django/apps/base.py +++ b/django/apps/base.py @@ -126,6 +126,32 @@ class AppConfig(object): raise LookupError( "App '%s' doesn't have a '%s' model." % (self.label, model_name)) + def get_models(self, include_auto_created=False, + include_deferred=False, include_swapped=False): + """ + Returns an iterable of models. + + By default, the following models aren't included: + + - auto-created models for many-to-many relations without + an explicit intermediate table, + - models created to satisfy deferred attribute queries, + - models that have been swapped out. + + Set the corresponding keyword argument to True to include such models. + Keyword arguments aren't documented; they're a private API. + + This method assumes that apps.populate_models() has run. + """ + for model in self.models.values(): + if model._deferred and not include_deferred: + continue + if model._meta.auto_created and not include_auto_created: + continue + if model._meta.swapped and not include_swapped: + continue + yield model + def import_models(self, all_models): # Dictionary of models for this app, primarily maintained in the # 'all_models' attribute of the Apps this AppConfig is attached to. diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index f933b61c86..e24cdd6865 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -74,14 +74,12 @@ def create_permissions(app_config, verbosity=22, interactive=True, db=DEFAULT_DB from django.contrib.contenttypes.models import ContentType - app_models = apps.get_models(app_config.models_module) - # This will hold the permissions we're looking for as # (content_type, (codename, name)) searched_perms = list() # The codenames and ctypes that should exist. ctypes = set() - for klass in app_models: + for klass in app_config.get_models(): # Force looking up the content types in the current database # before creating foreign keys to them. ctype = ContentType.objects.db_manager(db).get_for_model(klass) diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py index a7b47456a6..1b499d85f1 100644 --- a/django/contrib/contenttypes/management.py +++ b/django/contrib/contenttypes/management.py @@ -23,15 +23,15 @@ def update_contenttypes(app_config, verbosity=2, interactive=True, db=DEFAULT_DB return ContentType.objects.clear_cache() - app_models = apps.get_models(app_config.models_module) - if not app_models: - return - # They all have the same app_label, get the first one. - app_label = app_models[0]._meta.app_label + + app_label = app_config.label + app_models = dict( (model._meta.model_name, model) - for model in app_models - ) + for model in app_config.get_models()) + + if not app_models: + return # Get all the content types content_types = dict( diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py index c4501c5b24..d4d8b54af6 100644 --- a/django/core/management/commands/dumpdata.py +++ b/django/core/management/commands/dumpdata.py @@ -169,7 +169,7 @@ def sort_dependencies(app_list): models = set() for app_config, model_list in app_list: if model_list is None: - model_list = apps.get_models(app_config.models_module) + model_list = app_config.get_models() for model in model_list: models.add(model) diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py index d32ff3c5d0..65fee8183f 100644 --- a/django/core/management/commands/sqlsequencereset.py +++ b/django/core/management/commands/sqlsequencereset.py @@ -23,6 +23,6 @@ class Command(AppCommand): if app_config.models_module is None: return connection = connections[options.get('database')] - models = apps.get_models(app_config.models_module, include_auto_created=True) + models = app_config.get_models(include_auto_created=True) statements = connection.ops.sequence_reset_sql(self.style, models) return '\n'.join(statements) diff --git a/docs/ref/applications.txt b/docs/ref/applications.txt index 1fc74f6bee..8505784737 100644 --- a/docs/ref/applications.txt +++ b/docs/ref/applications.txt @@ -156,6 +156,10 @@ Read-only attributes Methods ------- +.. method:: AppConfig.get_models() + + Returns an iterable of :class:`~django.db.models.Model` classes. + .. method:: AppConfig.get_model(model_name) Returns the :class:`~django.db.models.Model` with the given