Loading django/apps/registry.py +7 −25 Original line number Diff line number Diff line Loading @@ -27,10 +27,6 @@ class Apps(object): if master and hasattr(sys.modules[__name__], 'apps'): raise RuntimeError("You may create only one master registry.") # When master is set to False, the registry ignores the only_installed # arguments to get_model[s]. self.master = master # Mapping of app labels => model names => model classes. Every time a # model is imported, ModelBase.__new__ calls apps.register_model which # creates an entry in all_models. All imported models are registered, Loading Loading @@ -190,9 +186,8 @@ class Apps(object): # This method is performance-critical at least for Django's test suite. @lru_cache.lru_cache(maxsize=None) def get_models(self, app_mod=None, include_auto_created=False, include_deferred=False, only_installed=True, include_swapped=False): def get_models(self, app_mod=None, include_auto_created=False, include_deferred=False, include_swapped=False): """ Given a module containing models, returns a list of the models. Otherwise returns a list of all installed models. Loading @@ -205,33 +200,20 @@ class Apps(object): queries are *not* included in the list of models. However, if you specify include_deferred, they will be. By default, models that aren't part of installed apps will *not* be included in the list of models. However, if you specify only_installed=False, they will be. If you're using a non-default Apps, this argument does nothing - all models will be included. By default, models that have been swapped out will *not* be included in the list of models. However, if you specify include_swapped, they will be. """ if not self.master: only_installed = False model_list = None self.populate_models() if app_mod: app_label = app_mod.__name__.split('.')[-2] if only_installed: try: model_dicts = [self.app_configs[app_label].models] except KeyError: model_dicts = [] else: model_dicts = [self.all_models[app_label]] else: if only_installed: model_dicts = [app_config.models for app_config in self.app_configs.values()] else: model_dicts = self.all_models.values() model_list = [] for model_dict in model_dicts: model_list.extend( Loading django/db/models/options.py +2 −2 Original line number Diff line number Diff line Loading @@ -514,7 +514,7 @@ class Options(object): cache[obj] = model # Collect also objects which are in relation to some proxy child/parent of self. proxy_cache = cache.copy() for klass in self.apps.get_models(include_auto_created=True, only_installed=False): for klass in self.apps.get_models(include_auto_created=True): if not klass._meta.swapped: for f in klass._meta.local_fields: if f.rel and not isinstance(f.rel.to, six.string_types) and f.generate_reverse_relation: Loading Loading @@ -557,7 +557,7 @@ class Options(object): cache[obj] = parent else: cache[obj] = model for klass in self.apps.get_models(only_installed=False): for klass in self.apps.get_models(): if not klass._meta.swapped: for f in klass._meta.local_many_to_many: if (f.rel Loading docs/releases/1.7.txt +6 −2 Original line number Diff line number Diff line Loading @@ -593,6 +593,10 @@ methods are only referring to fields or other items in ``model._meta``. App-loading changes ~~~~~~~~~~~~~~~~~~~ You should make sure that your project doesn't import models from applications that aren't in :setting:`INSTALLED_APPS`. Relations involving such models may not be created properly. Subclasses of :class:`~django.core.management.AppCommand` must now implement a :meth:`~django.core.management.AppCommand.handle_app_config` method instead of ``handle_app()``. This method receives an :class:`~django.apps.AppConfig` instance. Loading @@ -609,8 +613,8 @@ period. In addition, the following changes take effect immediately: * ``get_model`` raises :exc:`~exceptions.LookupError` instead of returning ``None`` when no model is found. * The ``only_installed`` and ``seed_cache`` arguments of ``get_model`` no longer exist. * The ``only_installed`` argument of ``get_model`` and ``get_models`` no longer exists, nor does the ``seed_cache`` argument of ``get_model``. While the new implementation is believed to be more robust, regressions cannot be ruled out, especially during the import sequence. Circular imports that Loading tests/app_loading/tests.py +0 −13 Original line number Diff line number Diff line Loading @@ -82,16 +82,3 @@ class GetModelsTest(TestCase): def test_get_models_with_app_label_only_returns_installed_models(self): self.assertEqual(apps.get_models(self.not_installed_module), []) def test_get_models_with_not_installed(self): self.assertIn( "NotInstalledModel", [m.__name__ for m in apps.get_models(only_installed=False)]) class NotInstalledModelsTest(TestCase): def test_related_not_installed_model(self): from .not_installed.models import NotInstalledModel self.assertEqual( set(NotInstalledModel._meta.get_all_field_names()), set(["id", "relatedmodel", "m2mrelatedmodel"])) Loading
django/apps/registry.py +7 −25 Original line number Diff line number Diff line Loading @@ -27,10 +27,6 @@ class Apps(object): if master and hasattr(sys.modules[__name__], 'apps'): raise RuntimeError("You may create only one master registry.") # When master is set to False, the registry ignores the only_installed # arguments to get_model[s]. self.master = master # Mapping of app labels => model names => model classes. Every time a # model is imported, ModelBase.__new__ calls apps.register_model which # creates an entry in all_models. All imported models are registered, Loading Loading @@ -190,9 +186,8 @@ class Apps(object): # This method is performance-critical at least for Django's test suite. @lru_cache.lru_cache(maxsize=None) def get_models(self, app_mod=None, include_auto_created=False, include_deferred=False, only_installed=True, include_swapped=False): def get_models(self, app_mod=None, include_auto_created=False, include_deferred=False, include_swapped=False): """ Given a module containing models, returns a list of the models. Otherwise returns a list of all installed models. Loading @@ -205,33 +200,20 @@ class Apps(object): queries are *not* included in the list of models. However, if you specify include_deferred, they will be. By default, models that aren't part of installed apps will *not* be included in the list of models. However, if you specify only_installed=False, they will be. If you're using a non-default Apps, this argument does nothing - all models will be included. By default, models that have been swapped out will *not* be included in the list of models. However, if you specify include_swapped, they will be. """ if not self.master: only_installed = False model_list = None self.populate_models() if app_mod: app_label = app_mod.__name__.split('.')[-2] if only_installed: try: model_dicts = [self.app_configs[app_label].models] except KeyError: model_dicts = [] else: model_dicts = [self.all_models[app_label]] else: if only_installed: model_dicts = [app_config.models for app_config in self.app_configs.values()] else: model_dicts = self.all_models.values() model_list = [] for model_dict in model_dicts: model_list.extend( Loading
django/db/models/options.py +2 −2 Original line number Diff line number Diff line Loading @@ -514,7 +514,7 @@ class Options(object): cache[obj] = model # Collect also objects which are in relation to some proxy child/parent of self. proxy_cache = cache.copy() for klass in self.apps.get_models(include_auto_created=True, only_installed=False): for klass in self.apps.get_models(include_auto_created=True): if not klass._meta.swapped: for f in klass._meta.local_fields: if f.rel and not isinstance(f.rel.to, six.string_types) and f.generate_reverse_relation: Loading Loading @@ -557,7 +557,7 @@ class Options(object): cache[obj] = parent else: cache[obj] = model for klass in self.apps.get_models(only_installed=False): for klass in self.apps.get_models(): if not klass._meta.swapped: for f in klass._meta.local_many_to_many: if (f.rel Loading
docs/releases/1.7.txt +6 −2 Original line number Diff line number Diff line Loading @@ -593,6 +593,10 @@ methods are only referring to fields or other items in ``model._meta``. App-loading changes ~~~~~~~~~~~~~~~~~~~ You should make sure that your project doesn't import models from applications that aren't in :setting:`INSTALLED_APPS`. Relations involving such models may not be created properly. Subclasses of :class:`~django.core.management.AppCommand` must now implement a :meth:`~django.core.management.AppCommand.handle_app_config` method instead of ``handle_app()``. This method receives an :class:`~django.apps.AppConfig` instance. Loading @@ -609,8 +613,8 @@ period. In addition, the following changes take effect immediately: * ``get_model`` raises :exc:`~exceptions.LookupError` instead of returning ``None`` when no model is found. * The ``only_installed`` and ``seed_cache`` arguments of ``get_model`` no longer exist. * The ``only_installed`` argument of ``get_model`` and ``get_models`` no longer exists, nor does the ``seed_cache`` argument of ``get_model``. While the new implementation is believed to be more robust, regressions cannot be ruled out, especially during the import sequence. Circular imports that Loading
tests/app_loading/tests.py +0 −13 Original line number Diff line number Diff line Loading @@ -82,16 +82,3 @@ class GetModelsTest(TestCase): def test_get_models_with_app_label_only_returns_installed_models(self): self.assertEqual(apps.get_models(self.not_installed_module), []) def test_get_models_with_not_installed(self): self.assertIn( "NotInstalledModel", [m.__name__ for m in apps.get_models(only_installed=False)]) class NotInstalledModelsTest(TestCase): def test_related_not_installed_model(self): from .not_installed.models import NotInstalledModel self.assertEqual( set(NotInstalledModel._meta.get_all_field_names()), set(["id", "relatedmodel", "m2mrelatedmodel"]))