| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
| |
|
|
|
|
| |
Refs #15903, #15866, #15850.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Returning None on errors required unpythonic error checking and was
inconsistent with get_app_config.
get_model was a private API until the previous commit, but given that it
was certainly used in third party software, the change is explained in
the release notes.
Applied the same change to get_registered_model, which is a new private
API introduced during the recent refactoring.
|
|
|
|
| |
Documented them as public APIs.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
register_model is called exactly once in the entire Django code base, at the
bottom of ModelBase.__new__:
new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
ModelBase.__new__ exits prematurely 120 lines earlier (sigh) if a model with
the same name is already registered:
if new_class._meta.apps.get_registered_model(new_class._meta.app_label, name):
return
(This isn't the exact code, but it's equivalent.)
apps.register_model and apps.get_registered_model are essentially a setter and
a getter for apps.all_models, and apps.register_model is the only setter. As a
consequence, new_class._meta.apps.all_models cannot change in-between.
Considering that name == new_class.__name__, we can conclude that
register_model(app_label, model) is always called with such arguments that
get_registered_model(app_label, model.__name__) returns None.
Considering that model._meta.model_name == model.__name__.lower(), and looking
at the implementation of register_model and get_registered_model, this proves
that self.all_models[app_label] doesn't contain model._meta.model_name in
register_model, allowing us to simplify the implementation.
|
|
|
|
| |
The u prefix looks bad on Python 2.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
Eliminated the app_ prefix that was more confusing than useful.
|
|
|
|
|
|
| |
Previously the _apps/models_loaded flags could remain set to False if
set_installed_apps exited with an exception, which is going to happen as
soon as we add tests for invalid values of INSTALLED_APPS.
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
Also renamed app_cache to apps and "app cache" to "app registry".
Deprecated AppCache.app_cache_ready() in favor of Apps.ready().
|
| |
|
|
|
|
|
| |
Invalidate properly the cache whenever all_models or app_configs change.
This fixes some isolation issues in the test suite.
|
|
|
|
|
|
|
| |
an exception.
Previously, this would corrupt the settings, because __exit__ isn't
called when __enter__raises an exception.
|
| |
|
|
|
|
|
| |
It's now easier to achieve the same effect with modify_settings or
override_settings.
|
|
|
|
|
|
|
|
|
|
| |
* Introduced [un]set_installed_apps to handle changes to the
INSTALLED_APPS setting.
* Refactored [un]set_available_apps to share its implementation
with [un]set_installed_apps.
* Implemented a receiver to clear some app-related caches.
* Removed test_missing_app as it is basically impossible to reproduce
this situation with public methods of the new app cache.
|
| |
|
|
|
|
| |
That matches its return type better.
|
|
|
|
| |
That matches its name ad its purpose better.
|
|
|
|
| |
It is a public API.
|
|
|
|
| |
Reverted 4a56a93cc458e9ab4dcab95d9f5067d4975dd1a2.
|
| |
|
| |
|
|
|
|
| |
Thanks Florian for catching this mistake.
|
|
|
|
|
|
|
| |
This commit reverts f44c4a5d0f and 39bbd165.
django.test.simple will be updated in a separate commit as it requires
invasive changes.
|
| |
|
| |
|
|
|
|
|
|
| |
Several parts of Django call get_apps() with a comment along this lines
of "this has the side effect of calling _populate()". I fail to see how
this is better than just calling populate()!
|
|
|
|
|
| |
Since it's never called with more than one model at a time the current
signature is needlessly complicated.
|
|
|
|
|
| |
It feels more natural for self.available_apps to contain app names (like
INSTALLED_APPS) than app labels, and this is easy to implement now.
|
| |
|
|
|
|
|
|
| |
Refactored get_apps() to rely on that method.
This commit is fully backwards-compatible.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Refactored get_app() to rely on that method.
get_app() starts by calling _populate(), which goes through
INSTALLED_APPS and, for each app, imports the app module and attempts to
import the models module. At this point, no further imports are
necessary to return the models module for a given app. Therefore, the
implementation of get_app() can be simplified and the safeguards for
race conditions can be removed.
Besides, the emptyOK parameter isn't used anywhere in Django. It was
introduced in d6c95e93 but not actually used nor documented, and it has
just been carried around since then. Since it's an obscure private API,
it's acceptable to stop supporting it without a deprecation path. This
branch aims at providing first-class support for applications without a
models module eventually.
For backwards-compatibility, get_app() still raises ImproperlyConfigured
when an app isn't found, even though LookupError is technically more
correct. I haven't gone as far as to preserve the exact error messages.
I've adjusted a few tests instead.
|
|
|
|
| |
Marginally improved creation of AppConfig stubs for non-installed apps.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
get_app_errors() always returned an empty dictionary; this behavior is
preserved in django.db.models.loading until that module is deprecated.
|
|
|
|
|
|
| |
the app cache.
This is a step towards allowing applications without a models module.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since the original ones in django.db.models.loading were kept only for
backwards compatibility, there's no need to recreate them. However, many
internals of Django still relied on them.
They were also imported in django.db.models. They never appear in the
documentation, except a quick mention of get_models and get_app in the
1.2 release notes to document an edge case in GIS. I don't think that
makes them a public API.
This commit doesn't change the overall amount of global state but
clarifies that it's tied to the app_cache object instead of hiding it
behind half a dozen functions.
|
|
|
|
|
|
| |
Its only difference with OrderedDict is that it didn't deepcopy its
keys. However it wasn't used anywhere with models modules as keys, only
as values. So this commit doesn't result in any change in functionality.
|
|
|
|
|
| |
It was only storing redundant information. This is part of the effort to
allow applications without a models module.
|
|
This commit doesn't contain any code changes; it's purely a refactoring.
|