Since it triggers imports, it shouldn't be done lightly.
This commit adds a public API for doing it explicitly, django.setup(),
and does it automatically when using manage.py and wsgi.py.
This removes the gap between the master app registry and ad-hoc app
registries created by the migration framework, specifically in terms
of behavior of the get_model[s] methods.
This commit contains a stealth feature that I'd rather not describe.
It raises ImportError whenever an entry in INSTALLED_APPS points
(directly or indirectly via AppConfig.name) to a non-existing module
and ImproperlyConfigured in all other cases.
Catching ImportError and re-raising ImproperlyConfigured tends to make
circular imports more difficult to diagnose.
This commit is a refactoring with no change of functionality, according
to the following invariants:
- An app_label that was in app_configs and app_models stays in
app_config and has its 'installed' attribute set to True.
- An app_label that was in app_models but not in app_configs is added to
app_configs and has its 'installed' attribute set to True.
As a consequence, all the code that iterated on app_configs is modified
to check for the 'installed' attribute. Code that iterated on app_models
is rewritten in terms of app_configs.
Many tests that stored and restored the state of the app cache were
updated.
In the long term, we should reconsider the usefulness of allowing
importing models from non-installed applications. This doesn't sound
particularly useful, can be a trap in some circumstances, and causes
significant complexity in sensitive areas of Django.