diff --git a/django/apps/base.py b/django/apps/base.py index cd8b008017c..778419fbef4 100644 --- a/django/apps/base.py +++ b/django/apps/base.py @@ -26,7 +26,7 @@ class AppConfig(object): self.models_module = models_module # Mapping of lower case model names to model classes. - # Populated by AppCache.register_models(). + # Populated by calls to AppCache.register_model(). self.models = OrderedDict() # Whether the app is in INSTALLED_APPS or was automatically created diff --git a/django/apps/cache.py b/django/apps/cache.py index 32c57371cb8..b125d6b4c6f 100644 --- a/django/apps/cache.py +++ b/django/apps/cache.py @@ -302,32 +302,27 @@ class BaseAppCache(object): except KeyError: return None - def register_models(self, app_label, *models): - """ - Register a set of models as belonging to an app. - """ - if models: - try: - app_config = self.app_configs[app_label] - except KeyError: - app_config = AppConfig._stub(app_label) - self.app_configs[app_label] = app_config - for model in models: - # Add the model to the app_config's models dictionary. - model_name = model._meta.model_name - model_dict = app_config.models - if model_name in model_dict: - # The same model may be imported via different paths (e.g. - # appname.models and project.appname.models). We use the source - # filename as a means to detect identity. - fname1 = os.path.abspath(upath(sys.modules[model.__module__].__file__)) - fname2 = os.path.abspath(upath(sys.modules[model_dict[model_name].__module__].__file__)) - # Since the filename extension could be .py the first time and - # .pyc or .pyo the second time, ignore the extension when - # comparing. - if os.path.splitext(fname1)[0] == os.path.splitext(fname2)[0]: - continue - model_dict[model_name] = model + def register_model(self, app_label, model): + try: + app_config = self.app_configs[app_label] + except KeyError: + app_config = AppConfig._stub(app_label) + self.app_configs[app_label] = app_config + # Add the model to the app_config's models dictionary. + model_name = model._meta.model_name + model_dict = app_config.models + if model_name in model_dict: + # The same model may be imported via different paths (e.g. + # appname.models and project.appname.models). We use the source + # filename as a means to detect identity. + fname1 = os.path.abspath(upath(sys.modules[model.__module__].__file__)) + fname2 = os.path.abspath(upath(sys.modules[model_dict[model_name].__module__].__file__)) + # Since the filename extension could be .py the first time and + # .pyc or .pyo the second time, ignore the extension when + # comparing. + if os.path.splitext(fname1)[0] == os.path.splitext(fname2)[0]: + return + model_dict[model_name] = model self._get_models_cache.clear() def set_available_apps(self, available): @@ -383,6 +378,16 @@ class BaseAppCache(object): app_paths.append(self._get_app_path(app)) return app_paths + def register_models(self, app_label, *models): + """ + Register a set of models as belonging to an app. + """ + warnings.warn( + "register_models(app_label, models) is deprecated.", + PendingDeprecationWarning, stacklevel=2) + for model in models: + self.register_model(app_label, model) + class AppCache(BaseAppCache): """ diff --git a/django/db/models/base.py b/django/db/models/base.py index 94d72341425..1d514ae1e26 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -274,7 +274,7 @@ class ModelBase(type): new_class._prepare() - new_class._meta.app_cache.register_models(new_class._meta.app_label, new_class) + new_class._meta.app_cache.register_model(new_class._meta.app_label, new_class) # Because of the way imports happen (recursively), we may or may not be # the first time this model tries to register with the framework. There # should only be one class for each model, so we always return the diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index bad1b307dba..a9503e94a87 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -151,7 +151,7 @@ class MakeMigrationsTests(MigrationTestBase): def test_files_content(self): self.assertTableNotExists("migrations_unicodemodel") - app_cache.register_models('migrations', UnicodeModel) + app_cache.register_model('migrations', UnicodeModel) with override_settings(MIGRATION_MODULES={"migrations": self.migration_pkg}): call_command("makemigrations", "migrations", verbosity=0) @@ -187,7 +187,7 @@ class MakeMigrationsTests(MigrationTestBase): def test_failing_migration(self): #21280 - If a migration fails to serialize, it shouldn't generate an empty file. - app_cache.register_models('migrations', UnserializableModel) + app_cache.register_model('migrations', UnserializableModel) with six.assertRaisesRegex(self, ValueError, r'Cannot serialize'): with override_settings(MIGRATION_MODULES={"migrations": self.migration_pkg}):