Removed the only_installed argument of Apps.get_models.

Refs #15903, #15866, #15850.
This commit is contained in:
Aymeric Augustin 2013-12-28 18:27:33 +01:00
parent ba7206cd81
commit 9f13c33281
4 changed files with 15 additions and 42 deletions

View File

@ -27,10 +27,6 @@ class Apps(object):
if master and hasattr(sys.modules[__name__], 'apps'): if master and hasattr(sys.modules[__name__], 'apps'):
raise RuntimeError("You may create only one master registry.") 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 # Mapping of app labels => model names => model classes. Every time a
# model is imported, ModelBase.__new__ calls apps.register_model which # model is imported, ModelBase.__new__ calls apps.register_model which
# creates an entry in all_models. All imported models are registered, # creates an entry in all_models. All imported models are registered,
@ -190,9 +186,8 @@ class Apps(object):
# This method is performance-critical at least for Django's test suite. # This method is performance-critical at least for Django's test suite.
@lru_cache.lru_cache(maxsize=None) @lru_cache.lru_cache(maxsize=None)
def get_models(self, app_mod=None, def get_models(self, app_mod=None, include_auto_created=False,
include_auto_created=False, include_deferred=False, include_deferred=False, include_swapped=False):
only_installed=True, include_swapped=False):
""" """
Given a module containing models, returns a list of the models. Given a module containing models, returns a list of the models.
Otherwise returns a list of all installed models. Otherwise returns a list of all installed models.
@ -205,33 +200,20 @@ class Apps(object):
queries are *not* included in the list of models. However, if queries are *not* included in the list of models. However, if
you specify include_deferred, they will be. 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 By default, models that have been swapped out will *not* be
included in the list of models. However, if you specify included in the list of models. However, if you specify
include_swapped, they will be. include_swapped, they will be.
""" """
if not self.master:
only_installed = False
model_list = None model_list = None
self.populate_models() self.populate_models()
if app_mod: if app_mod:
app_label = app_mod.__name__.split('.')[-2] app_label = app_mod.__name__.split('.')[-2]
if only_installed:
try: try:
model_dicts = [self.app_configs[app_label].models] model_dicts = [self.app_configs[app_label].models]
except KeyError: except KeyError:
model_dicts = [] model_dicts = []
else: 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()] model_dicts = [app_config.models for app_config in self.app_configs.values()]
else:
model_dicts = self.all_models.values()
model_list = [] model_list = []
for model_dict in model_dicts: for model_dict in model_dicts:
model_list.extend( model_list.extend(

View File

@ -514,7 +514,7 @@ class Options(object):
cache[obj] = model cache[obj] = model
# Collect also objects which are in relation to some proxy child/parent of self. # Collect also objects which are in relation to some proxy child/parent of self.
proxy_cache = cache.copy() 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: if not klass._meta.swapped:
for f in klass._meta.local_fields: for f in klass._meta.local_fields:
if f.rel and not isinstance(f.rel.to, six.string_types) and f.generate_reverse_relation: if f.rel and not isinstance(f.rel.to, six.string_types) and f.generate_reverse_relation:
@ -557,7 +557,7 @@ class Options(object):
cache[obj] = parent cache[obj] = parent
else: else:
cache[obj] = model 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: if not klass._meta.swapped:
for f in klass._meta.local_many_to_many: for f in klass._meta.local_many_to_many:
if (f.rel if (f.rel

View File

@ -593,6 +593,10 @@ methods are only referring to fields or other items in ``model._meta``.
App-loading changes 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 Subclasses of :class:`~django.core.management.AppCommand` must now implement a
:meth:`~django.core.management.AppCommand.handle_app_config` method instead of :meth:`~django.core.management.AppCommand.handle_app_config` method instead of
``handle_app()``. This method receives an :class:`~django.apps.AppConfig` instance. ``handle_app()``. This method receives an :class:`~django.apps.AppConfig` instance.
@ -609,8 +613,8 @@ period. In addition, the following changes take effect immediately:
* ``get_model`` raises :exc:`~exceptions.LookupError` instead of returning * ``get_model`` raises :exc:`~exceptions.LookupError` instead of returning
``None`` when no model is found. ``None`` when no model is found.
* The ``only_installed`` and ``seed_cache`` arguments of ``get_model`` no * The ``only_installed`` argument of ``get_model`` and ``get_models`` no
longer exist. longer exists, nor does the ``seed_cache`` argument of ``get_model``.
While the new implementation is believed to be more robust, regressions cannot While the new implementation is believed to be more robust, regressions cannot
be ruled out, especially during the import sequence. Circular imports that be ruled out, especially during the import sequence. Circular imports that

View File

@ -82,16 +82,3 @@ class GetModelsTest(TestCase):
def test_get_models_with_app_label_only_returns_installed_models(self): def test_get_models_with_app_label_only_returns_installed_models(self):
self.assertEqual(apps.get_models(self.not_installed_module), []) 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"]))