diff --git a/django/apps/__init__.py b/django/apps/__init__.py index 6b47d3397f..074a448660 100644 --- a/django/apps/__init__.py +++ b/django/apps/__init__.py @@ -1,2 +1,2 @@ from .base import AppConfig # NOQA -from .cache import app_cache # NOQA +from .registry import apps # NOQA diff --git a/django/apps/base.py b/django/apps/base.py index 706ed54ef6..f1baaa5adf 100644 --- a/django/apps/base.py +++ b/django/apps/base.py @@ -97,8 +97,8 @@ class AppConfig(object): def import_models(self, all_models): # Dictionary of models for this app, stored in the 'all_models' - # attribute of the AppCache this AppConfig is attached to. Injected as - # a parameter because it may get populated before this method has run. + # attribute of the Apps this AppConfig is attached to. Injected as a + # parameter because it may get populated before this method has run. self.models = all_models if module_has_submodule(self.app_module, MODELS_MODULE_NAME): diff --git a/django/apps/cache.py b/django/apps/registry.py similarity index 94% rename from django/apps/cache.py rename to django/apps/registry.py index 92007f637a..0cb58f2049 100644 --- a/django/apps/cache.py +++ b/django/apps/registry.py @@ -14,25 +14,26 @@ from django.utils._os import upath from .base import AppConfig -class AppCache(object): +class Apps(object): """ - A cache that stores installed applications and their models. Used to - provide reverse-relations and for app introspection. + A registry that stores the configuration of installed applications. + + It also keeps track of models eg. to provide reverse-relations. """ def __init__(self, master=False): - # Only one master of the app-cache may exist at a given time, and it - # shall be the app_cache variable defined at the end of this module. - if master and hasattr(sys.modules[__name__], 'app_cache'): - raise RuntimeError("You may create only one master app cache.") + # Only one master registry may exist at a given time, and it shall be + # the apps variable defined at the end of this module. + if master and hasattr(sys.modules[__name__], 'apps'): + raise RuntimeError("You may create only one master registry.") - # When master is set to False, the app cache isn't populated from + # When master is set to False, the registry isn't populated from # INSTALLED_APPS and ignores the only_installed arguments to # get_model[s]. self.master = master # Mapping of app labels => model names => model classes. Used to - # register models before the app cache is populated and also for + # register models before the registry is populated and also for # applications that aren't installed. self.all_models = defaultdict(OrderedDict) @@ -43,7 +44,7 @@ class AppCache(object): # set_available_apps and set_installed_apps. self.stored_app_configs = [] - # Internal flags used when populating the master cache. + # Internal flags used when populating the master registry. self._apps_loaded = not self.master self._models_loaded = not self.master @@ -133,9 +134,9 @@ class AppCache(object): self.get_models.cache_clear() self._models_loaded = True - def app_cache_ready(self): + def ready(self): """ - Returns true if the model cache is fully populated. + Returns True if the registry is fully populated. Useful for code that wants to cache the results of get_models() for themselves once it is safe to do so. @@ -200,7 +201,7 @@ class AppCache(object): 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 - AppCache, this argument does nothing - all models will be included. + 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 @@ -272,11 +273,11 @@ class AppCache(object): def has_app(self, app_name): """ - Checks whether an application with this name exists in the app cache. + Checks whether an application with this name exists in the registry. app_name is the full name of the app eg. 'django.contrib.admin'. - It's safe to call this method at import time, even while the app cache + It's safe to call this method at import time, even while the registry is being populated. It returns None for apps that aren't loaded yet. """ app_config = self.app_configs.get(app_name.rpartition(".")[2]) @@ -286,7 +287,7 @@ class AppCache(object): """ Returns the model class if one is registered and None otherwise. - It's safe to call this method at import time, even while the app cache + It's safe to call this method at import time, even while the registry is being populated. It returns None for models that aren't loaded yet. """ return self.all_models[app_label].get(model_name.lower()) @@ -371,6 +372,12 @@ class AppCache(object): self.get_models.cache_clear() return app_config.models_module + def app_cache_ready(self): + warnings.warn( + "app_cache_ready() is deprecated.", + PendingDeprecationWarning, stacklevel=2) + return self.ready() + def get_app(self, app_label): """ Returns the module containing the models for the given app_label. @@ -446,4 +453,4 @@ class AppCache(object): self.register_model(app_label, model) -app_cache = AppCache(master=True) +apps = Apps(master=True) diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index c2a409a0e4..0edeca210e 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -6,7 +6,7 @@ from django.contrib.auth import logout as auth_logout, REDIRECT_FIELD_NAME from django.contrib.contenttypes import views as contenttype_views from django.views.decorators.csrf import csrf_protect from django.db.models.base import ModelBase -from django.apps import app_cache +from django.apps import apps from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.core.urlresolvers import reverse, NoReverseMatch from django.template.response import TemplateResponse @@ -160,11 +160,11 @@ class AdminSite(object): The default implementation checks that admin and contenttypes apps are installed, as well as the auth context processor. """ - app_cache.populate_apps() - if not app_cache.has_app('django.contrib.admin'): + apps.populate_apps() + if not apps.has_app('django.contrib.admin'): raise ImproperlyConfigured("Put 'django.contrib.admin' in your " "INSTALLED_APPS setting in order to use the admin application.") - if not app_cache.has_app('django.contrib.contenttypes'): + if not apps.has_app('django.contrib.contenttypes'): raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in " "your INSTALLED_APPS setting in order to use the admin application.") if 'django.contrib.auth.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: @@ -381,7 +381,7 @@ class AdminSite(object): app_dict[app_label]['models'].append(model_dict) else: app_dict[app_label] = { - 'name': app_cache.get_app_config(app_label).verbose_name, + 'name': apps.get_app_config(app_label).verbose_name, 'app_label': app_label, 'app_url': reverse('admin:app_list', kwargs={'app_label': app_label}, current_app=self.name), 'has_module_perms': has_module_perms, @@ -408,7 +408,7 @@ class AdminSite(object): def app_index(self, request, app_label, extra_context=None): user = request.user - app_name = app_cache.get_app_config(app_label).verbose_name + app_name = apps.get_app_config(app_label).verbose_name has_module_perms = user.has_module_perms(app_label) if not has_module_perms: raise PermissionDenied diff --git a/django/contrib/admin/templatetags/admin_static.py b/django/contrib/admin/templatetags/admin_static.py index 7c7a5e5654..446ab4cab5 100644 --- a/django/contrib/admin/templatetags/admin_static.py +++ b/django/contrib/admin/templatetags/admin_static.py @@ -1,9 +1,9 @@ -from django.apps import app_cache +from django.apps import apps from django.template import Library register = Library() -if app_cache.has_app('django.contrib.staticfiles'): +if apps.has_app('django.contrib.staticfiles'): from django.contrib.staticfiles.templatetags.staticfiles import static else: from django.templatetags.static import static diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py index 18e3ad48f8..23dba7c7bd 100644 --- a/django/contrib/admin/validation.py +++ b/django/contrib/admin/validation.py @@ -1,4 +1,4 @@ -from django.apps import app_cache +from django.apps import apps from django.core.exceptions import ImproperlyConfigured from django.db import models from django.db.models.fields import FieldDoesNotExist @@ -16,9 +16,9 @@ __all__ = ['BaseValidator', 'InlineValidator'] class BaseValidator(object): def __init__(self): - # Before we can introspect models, they need the app cache to be fully - # loaded so that inter-relations are set up correctly. - app_cache.populate_models() + # Before we can introspect models, they need the app registry to be + # fully loaded so that inter-relations are set up correctly. + apps.populate_models() def validate(self, cls, model): for m in dir(self): diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py index 973c81ddaf..ebb7687dea 100644 --- a/django/contrib/admindocs/views.py +++ b/django/contrib/admindocs/views.py @@ -5,7 +5,7 @@ import re import warnings from django import template -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.contrib import admin from django.contrib.admin.views.decorators import staff_member_required @@ -174,7 +174,7 @@ class ModelIndexView(BaseAdminDocsView): template_name = 'admin_doc/model_index.html' def get_context_data(self, **kwargs): - m_list = [m._meta for m in app_cache.get_models()] + m_list = [m._meta for m in apps.get_models()] kwargs.update({'models': m_list}) return super(ModelIndexView, self).get_context_data(**kwargs) @@ -185,10 +185,10 @@ class ModelDetailView(BaseAdminDocsView): def get_context_data(self, **kwargs): # Get the model class. try: - app_cache.get_app_config(self.kwargs['app_label']) + apps.get_app_config(self.kwargs['app_label']) except LookupError: raise Http404(_("App %(app_label)r not found") % self.kwargs) - model = app_cache.get_model(self.kwargs['app_label'], self.kwargs['model_name']) + model = apps.get_model(self.kwargs['app_label'], self.kwargs['model_name']) if model is None: raise Http404(_("Model %(model_name)r not found in app %(app_label)r") % self.kwargs) diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py index 3c5a40c184..ef44737cc0 100644 --- a/django/contrib/auth/__init__.py +++ b/django/contrib/auth/__init__.py @@ -123,13 +123,13 @@ def get_user_model(): """ Returns the User model that is active in this project. """ - from django.apps import app_cache + from django.apps import apps try: app_label, model_name = settings.AUTH_USER_MODEL.split('.') except ValueError: raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'") - user_model = app_cache.get_model(app_label, model_name) + user_model = apps.get_model(app_label, model_name) if user_model is None: raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL) return user_model diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 008661fac6..c2111e3b98 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import getpass import unicodedata -from django.apps import app_cache +from django.apps import apps from django.contrib.auth import (models as auth_app, get_permission_codename, get_user_model) from django.core import exceptions @@ -61,7 +61,7 @@ def _check_permission_clashing(custom, builtin, ctype): def create_permissions(app, created_models, verbosity, db=DEFAULT_DB_ALIAS, **kwargs): - if app_cache.get_model('auth', 'Permission') is None: + if apps.get_model('auth', 'Permission') is None: return if not router.allow_migrate(db, auth_app.Permission): @@ -69,7 +69,7 @@ def create_permissions(app, created_models, verbosity, db=DEFAULT_DB_ALIAS, **kw from django.contrib.contenttypes.models import ContentType - app_models = app_cache.get_models(app) + app_models = apps.get_models(app) # This will hold the permissions we're looking for as # (content_type, (codename, name)) @@ -117,7 +117,7 @@ def create_permissions(app, created_models, verbosity, db=DEFAULT_DB_ALIAS, **kw def create_superuser(app, created_models, verbosity, db, **kwargs): - if app_cache.get_model('auth', 'Permission') is None: + if apps.get_model('auth', 'Permission') is None: return UserModel = get_user_model() diff --git a/django/contrib/auth/tests/test_management.py b/django/contrib/auth/tests/test_management.py index 57c986ac8a..838c8650fc 100644 --- a/django/contrib/auth/tests/test_management.py +++ b/django/contrib/auth/tests/test_management.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from datetime import date -from django.apps import app_cache +from django.apps import apps from django.contrib.auth import models, management from django.contrib.auth.management import create_permissions from django.contrib.auth.management.commands import changepassword @@ -183,21 +183,21 @@ class CustomUserModelValidationTestCase(TestCase): def test_required_fields_is_list(self): "REQUIRED_FIELDS should be a list." new_io = StringIO() - get_validation_errors(new_io, app_cache.get_app_config('auth').models_module) + get_validation_errors(new_io, apps.get_app_config('auth').models_module) self.assertIn("The REQUIRED_FIELDS must be a list or tuple.", new_io.getvalue()) @override_settings(AUTH_USER_MODEL='auth.CustomUserBadRequiredFields') def test_username_not_in_required_fields(self): "USERNAME_FIELD should not appear in REQUIRED_FIELDS." new_io = StringIO() - get_validation_errors(new_io, app_cache.get_app_config('auth').models_module) + get_validation_errors(new_io, apps.get_app_config('auth').models_module) self.assertIn("The field named as the USERNAME_FIELD should not be included in REQUIRED_FIELDS on a swappable User model.", new_io.getvalue()) @override_settings(AUTH_USER_MODEL='auth.CustomUserNonUniqueUsername') def test_username_non_unique(self): "A non-unique USERNAME_FIELD should raise a model validation error." new_io = StringIO() - get_validation_errors(new_io, app_cache.get_app_config('auth').models_module) + get_validation_errors(new_io, apps.get_app_config('auth').models_module) self.assertIn("The USERNAME_FIELD must be unique. Add unique=True to the field parameters.", new_io.getvalue()) diff --git a/django/contrib/comments/__init__.py b/django/contrib/comments/__init__.py index f265875c36..a6286b48ed 100644 --- a/django/contrib/comments/__init__.py +++ b/django/contrib/comments/__init__.py @@ -1,6 +1,6 @@ from importlib import import_module import warnings -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core import urlresolvers from django.core.exceptions import ImproperlyConfigured @@ -16,7 +16,7 @@ def get_comment_app(): Get the comment app (i.e. "django.contrib.comments") as defined in the settings """ try: - app_config = app_cache.get_app_config(get_comment_app_name().rpartition(".")[2]) + app_config = apps.get_app_config(get_comment_app_name().rpartition(".")[2]) except LookupError: raise ImproperlyConfigured("The COMMENTS_APP (%r) " "must be in INSTALLED_APPS" % settings.COMMENTS_APP) diff --git a/django/contrib/comments/views/comments.py b/django/contrib/comments/views/comments.py index 5d7c543adb..bad8eb50f7 100644 --- a/django/contrib/comments/views/comments.py +++ b/django/contrib/comments/views/comments.py @@ -1,5 +1,5 @@ from django import http -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.contrib import comments from django.contrib.comments import signals @@ -49,7 +49,7 @@ def post_comment(request, next=None, using=None): if ctype is None or object_pk is None: return CommentPostBadRequest("Missing content_type or object_pk field.") try: - model = app_cache.get_model(*ctype.split(".", 1)) + model = apps.get_model(*ctype.split(".", 1)) target = model._default_manager.using(using).get(pk=object_pk) except TypeError: return CommentPostBadRequest( diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py index 4ea10ebe58..87171b1ff2 100644 --- a/django/contrib/contenttypes/management.py +++ b/django/contrib/contenttypes/management.py @@ -1,4 +1,4 @@ -from django.apps import app_cache +from django.apps import apps from django.contrib.contenttypes.models import ContentType from django.db import DEFAULT_DB_ALIAS, router from django.db.models import signals @@ -12,14 +12,14 @@ def update_contenttypes(app, created_models, verbosity=2, db=DEFAULT_DB_ALIAS, * Creates content types for models in the given app, removing any model entries that no longer have a matching model class. """ - if app_cache.get_model('contenttypes', 'ContentType') is None: + if apps.get_model('contenttypes', 'ContentType') is None: return if not router.allow_migrate(db, ContentType): return ContentType.objects.clear_cache() - app_models = app_cache.get_models(app) + app_models = apps.get_models(app) if not app_models: return # They all have the same app_label, get the first one. @@ -84,7 +84,7 @@ If you're unsure, answer 'no'. def update_all_contenttypes(verbosity=2, **kwargs): - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): update_contenttypes(app_config.models_module, None, verbosity, **kwargs) signals.post_migrate.connect(update_contenttypes) diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py index 90dea5b811..6df1087cae 100644 --- a/django/contrib/contenttypes/models.py +++ b/django/contrib/contenttypes/models.py @@ -1,4 +1,4 @@ -from django.apps import app_cache +from django.apps import apps from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_text, force_text @@ -157,8 +157,7 @@ class ContentType(models.Model): def model_class(self): "Returns the Python model class for this type of content." - return app_cache.get_model(self.app_label, self.model, - only_installed=False) + return apps.get_model(self.app_label, self.model, only_installed=False) def get_object_for_this_type(self, **kwargs): """ diff --git a/django/contrib/gis/sitemaps/kml.py b/django/contrib/gis/sitemaps/kml.py index 1e4fc82550..74d7acd772 100644 --- a/django/contrib/gis/sitemaps/kml.py +++ b/django/contrib/gis/sitemaps/kml.py @@ -1,4 +1,4 @@ -from django.apps import app_cache +from django.apps import apps from django.core import urlresolvers from django.contrib.sitemaps import Sitemap from django.contrib.gis.db.models.fields import GeometryField @@ -26,7 +26,7 @@ class KMLSitemap(Sitemap): """ kml_sources = [] if sources is None: - sources = app_cache.get_models() + sources = apps.get_models() for source in sources: if isinstance(source, models.base.ModelBase): for field in source._meta.fields: diff --git a/django/contrib/gis/sitemaps/views.py b/django/contrib/gis/sitemaps/views.py index e68523981e..20a91130bb 100644 --- a/django/contrib/gis/sitemaps/views.py +++ b/django/contrib/gis/sitemaps/views.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals import warnings -from django.apps import app_cache +from django.apps import apps from django.http import HttpResponse, Http404 from django.template import loader from django.contrib.sites.models import get_current_site @@ -81,7 +81,7 @@ def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB must be that of a geographic field. """ placemarks = [] - klass = app_cache.get_model(label, model) + klass = apps.get_model(label, model) if not klass: raise Http404('You must supply a valid app label and module name. Got "%s.%s"' % (label, model)) diff --git a/django/contrib/messages/tests/base.py b/django/contrib/messages/tests/base.py index 54592e8d25..7244a6d34e 100644 --- a/django/contrib/messages/tests/base.py +++ b/django/contrib/messages/tests/base.py @@ -1,7 +1,7 @@ from unittest import skipUnless from django import http -from django.apps import app_cache +from django.apps import apps from django.conf import global_settings from django.contrib.messages import constants, utils, get_level, set_level from django.contrib.messages.api import MessageFailure @@ -15,7 +15,7 @@ from django.utils.translation import ugettext_lazy def skipUnlessAuthIsInstalled(func): return skipUnless( - app_cache.has_app('django.contrib.auth'), + apps.has_app('django.contrib.auth'), "django.contrib.auth isn't installed")(func) diff --git a/django/contrib/redirects/middleware.py b/django/contrib/redirects/middleware.py index c5b672659e..52c9a49a8f 100644 --- a/django/contrib/redirects/middleware.py +++ b/django/contrib/redirects/middleware.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.contrib.redirects.models import Redirect from django.contrib.sites.models import get_current_site @@ -15,7 +15,7 @@ class RedirectFallbackMiddleware(object): response_redirect_class = http.HttpResponsePermanentRedirect def __init__(self): - if not app_cache.has_app('django.contrib.sites'): + if not apps.has_app('django.contrib.sites'): raise ImproperlyConfigured( "You cannot use RedirectFallbackMiddleware when " "django.contrib.sites is not installed." diff --git a/django/contrib/sitemaps/tests/test_flatpages.py b/django/contrib/sitemaps/tests/test_flatpages.py index 90172e558f..4e9deb8de4 100644 --- a/django/contrib/sitemaps/tests/test_flatpages.py +++ b/django/contrib/sitemaps/tests/test_flatpages.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from unittest import skipUnless -from django.apps import app_cache +from django.apps import apps from django.conf import settings from .base import SitemapTestsBase @@ -10,7 +10,7 @@ from .base import SitemapTestsBase class FlatpagesSitemapTests(SitemapTestsBase): - @skipUnless(app_cache.has_app('django.contrib.flatpages'), + @skipUnless(apps.has_app('django.contrib.flatpages'), "django.contrib.flatpages app not installed.") def test_flatpage_sitemap(self): "Basic FlatPage sitemap test" diff --git a/django/contrib/sitemaps/tests/test_http.py b/django/contrib/sitemaps/tests/test_http.py index 583b0b44bf..e8c3409c74 100644 --- a/django/contrib/sitemaps/tests/test_http.py +++ b/django/contrib/sitemaps/tests/test_http.py @@ -4,7 +4,7 @@ import os from datetime import date from unittest import skipUnless -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.contrib.sitemaps import Sitemap, GenericSitemap from django.contrib.sites.models import Site @@ -118,7 +118,7 @@ class HTTPSitemapTests(SitemapTestsBase): """ % date.today() self.assertXMLEqual(response.content.decode('utf-8'), expected_content) - @skipUnless(app_cache.has_app('django.contrib.sites'), + @skipUnless(apps.has_app('django.contrib.sites'), "django.contrib.sites app not installed.") def test_sitemap_get_urls_no_site_1(self): """ diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py index de907ef8ef..eede6fbaa8 100644 --- a/django/contrib/staticfiles/finders.py +++ b/django/contrib/staticfiles/finders.py @@ -1,7 +1,7 @@ from collections import OrderedDict import os -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.files.storage import default_storage, Storage, FileSystemStorage @@ -43,7 +43,7 @@ class FileSystemFinder(BaseFinder): A static files finder that uses the ``STATICFILES_DIRS`` setting to locate files. """ - def __init__(self, apps=None, *args, **kwargs): + def __init__(self, app_names=None, *args, **kwargs): # List of locations with static files self.locations = [] # Maps dir paths to an appropriate storage instance @@ -114,15 +114,15 @@ class AppDirectoriesFinder(BaseFinder): """ storage_class = AppStaticStorage - def __init__(self, apps=None, *args, **kwargs): + def __init__(self, app_names=None, *args, **kwargs): # The list of apps that are handled self.apps = [] # Mapping of app names to storage instances self.storages = OrderedDict() - if apps is None: - app_configs = app_cache.get_app_configs() - apps = [app_config.name for app_config in app_configs] - for app in apps: + if app_names is None: + app_configs = apps.get_app_configs() + app_names = [app_config.name for app_config in app_configs] + for app in app_names: app_storage = self.storage_class(app) if os.path.isdir(app_storage.location): self.storages[app] = app_storage diff --git a/django/core/checks/compatibility/django_1_6_0.py b/django/core/checks/compatibility/django_1_6_0.py index a42249de60..1be727f70d 100644 --- a/django/core/checks/compatibility/django_1_6_0.py +++ b/django/core/checks/compatibility/django_1_6_0.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.db import models @@ -32,7 +32,7 @@ def check_boolean_field_default_value(): warns the user that the default has changed from False to Null. """ fields = [] - for cls in app_cache.get_models(): + for cls in apps.get_models(): opts = cls._meta for f in opts.local_fields: if isinstance(f, models.BooleanField) and not f.has_default(): diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index bc81b8f9d2..019837b35c 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -112,17 +112,17 @@ def get_commands(): except ImproperlyConfigured: # Still useful for commands that do not require functional # settings, like startproject or help. - apps = [] + app_names = [] else: - # Populate the app cache outside of the try/except block to avoid - # catching ImproperlyConfigured errors that aren't caused by the - # absence of a settings module. - from django.apps import app_cache - app_configs = app_cache.get_app_configs() - apps = [app_config.name for app_config in app_configs] + # Populate the app registry outside of the try/except block to + # avoid catching ImproperlyConfigured errors that aren't caused + # by the absence of a settings module. + from django.apps import apps + app_configs = apps.get_app_configs() + app_names = [app_config.name for app_config in app_configs] # Find and load the management module for each installed app. - for app_name in apps: + for app_name in app_names: try: path = find_management_module(app_name) _commands.update(dict((name, app_name) for name in find_commands(path))) @@ -346,8 +346,8 @@ class ManagementUtility(object): elif cwords[0] in ('dumpdata', 'sql', 'sqlall', 'sqlclear', 'sqlcustom', 'sqlindexes', 'sqlsequencereset', 'test'): try: - from django.apps import app_cache - app_configs = app_cache.get_app_configs() + from django.apps import apps + app_configs = apps.get_app_configs() # Get the last part of the dotted path as the app name. options += [(app_config.label, 0) for app_config in app_configs] except ImportError: diff --git a/django/core/management/base.py b/django/core/management/base.py index 101a486b40..5c3a1a6c8c 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -341,16 +341,16 @@ class AppCommand(BaseCommand): args = '' def handle(self, *app_labels, **options): - from django.apps import app_cache + from django.apps import apps if not app_labels: raise CommandError('Enter at least one appname.') # Populate models and don't use only_with_models_module=True when # calling get_app_config() to tell apart missing apps from apps # without a model module -- which can't be supported with the legacy # API since it passes the models module to handle_app(). - app_cache.populate_models() + apps.populate_models() try: - app_configs = [app_cache.get_app_config(app_label) for app_label in app_labels] + app_configs = [apps.get_app_config(app_label) for app_label in app_labels] except (LookupError, ImportError) as e: raise CommandError("%s. Are you sure your INSTALLED_APPS setting is correct?" % e) output = [] diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py index 9aebb6c7d6..f6b9e7a4c8 100644 --- a/django/core/management/commands/dumpdata.py +++ b/django/core/management/commands/dumpdata.py @@ -37,7 +37,7 @@ class Command(BaseCommand): args = '[appname appname.ModelName ...]' def handle(self, *app_labels, **options): - from django.apps import app_cache + from django.apps import apps format = options.get('format') indent = options.get('indent') @@ -63,13 +63,13 @@ class Command(BaseCommand): for exclude in excludes: if '.' in exclude: app_label, model_name = exclude.split('.', 1) - model_obj = app_cache.get_model(app_label, model_name) + model_obj = apps.get_model(app_label, model_name) if not model_obj: raise CommandError('Unknown model in excludes: %s' % exclude) excluded_models.add(model_obj) else: try: - app_obj = app_cache.get_app_config(exclude).models_module + app_obj = apps.get_app_config(exclude).models_module if app_obj is not None: excluded_apps.add(app_obj) except LookupError: @@ -79,7 +79,7 @@ class Command(BaseCommand): if primary_keys: raise CommandError("You can only use --pks option with one model") app_list = OrderedDict((app_config.models_module, None) - for app_config in app_cache.get_app_configs(only_with_models_module=True) + for app_config in apps.get_app_configs(only_with_models_module=True) if app_config.models_module not in excluded_apps) else: if len(app_labels) > 1 and primary_keys: @@ -89,12 +89,12 @@ class Command(BaseCommand): try: app_label, model_label = label.split('.') try: - app = app_cache.get_app_config(app_label).models_module + app = apps.get_app_config(app_label).models_module except LookupError: raise CommandError("Unknown application: %s" % app_label) if app is None or app in excluded_apps: continue - model = app_cache.get_model(app_label, model_label) + model = apps.get_model(app_label, model_label) if model is None: raise CommandError("Unknown model: %s.%s" % (app_label, model_label)) @@ -109,7 +109,7 @@ class Command(BaseCommand): # This is just an app - no model qualifier app_label = label try: - app = app_cache.get_app_config(app_label).models_module + app = apps.get_app_config(app_label).models_module except LookupError: raise CommandError("Unknown application: %s" % app_label) if app is None or app in excluded_apps: @@ -162,13 +162,13 @@ def sort_dependencies(app_list): is serialized before a normal model, and any model with a natural key dependency has it's dependencies serialized first. """ - from django.apps import app_cache + from django.apps import apps # Process the list of models, and get the list of dependencies model_dependencies = [] models = set() for app, model_list in app_list: if model_list is None: - model_list = app_cache.get_models(app) + model_list = apps.get_models(app) for model in model_list: models.add(model) @@ -176,7 +176,7 @@ def sort_dependencies(app_list): if hasattr(model, 'natural_key'): deps = getattr(model.natural_key, 'dependencies', []) if deps: - deps = [app_cache.get_model(*d.split('.')) for d in deps] + deps = [apps.get_model(*d.split('.')) for d in deps] else: deps = [] diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index 49007bf0a2..619df9536c 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -2,7 +2,7 @@ import sys from importlib import import_module from optparse import make_option -from django.apps import app_cache +from django.apps import apps from django.db import connections, router, transaction, DEFAULT_DB_ALIAS from django.core.management import call_command from django.core.management.base import NoArgsCommand, CommandError @@ -41,7 +41,7 @@ class Command(NoArgsCommand): # Import the 'management' module within each installed app, to register # dispatcher events. - for app_config in app_cache.get_app_configs(): + for app_config in apps.get_app_configs(): try: import_module('.management', app_config.name) except ImportError: @@ -93,6 +93,6 @@ Are you sure you want to do this? # Emit the post migrate signal. This allows individual applications to # respond as if the database had been migrated from scratch. all_models = [] - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): all_models.extend(router.get_migratable_models(app_config.models_module, database, include_auto_created=True)) emit_post_migrate_signal(set(all_models), verbosity, interactive, database) diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index bfeba68aa6..65bc96ba99 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -7,7 +7,7 @@ import warnings import zipfile from optparse import make_option -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core import serializers from django.core.management.base import BaseCommand, CommandError @@ -230,7 +230,7 @@ class Command(BaseCommand): current directory. """ dirs = [] - for app_config in app_cache.get_app_configs(): + for app_config in apps.get_app_configs(): d = os.path.join(app_config.path, 'fixtures') if os.path.isdir(d): dirs.append(d) diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index aaf0270840..411aec42b3 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -3,7 +3,7 @@ import os import operator from optparse import make_option -from django.apps import app_cache +from django.apps import apps from django.core.management.base import BaseCommand, CommandError from django.db import connections, DEFAULT_DB_ALIAS, migrations from django.db.migrations.loader import MigrationLoader @@ -37,7 +37,7 @@ class Command(BaseCommand): bad_app_labels = set() for app_label in app_labels: try: - app_cache.get_app_config(app_label) + apps.get_app_config(app_label) except LookupError: bad_app_labels.add(app_label) if bad_app_labels: @@ -72,7 +72,7 @@ class Command(BaseCommand): # Detect changes autodetector = MigrationAutodetector( loader.graph.project_state(), - ProjectState.from_app_cache(app_cache), + ProjectState.from_apps(apps), InteractiveMigrationQuestioner(specified_apps=app_labels), ) changes = autodetector.changes(graph=loader.graph, trim_to_apps=app_labels or None) diff --git a/django/core/management/commands/migrate.py b/django/core/management/commands/migrate.py index 05b4a62e87..1f5e9619c7 100644 --- a/django/core/management/commands/migrate.py +++ b/django/core/management/commands/migrate.py @@ -6,7 +6,7 @@ from importlib import import_module import itertools import traceback -from django.apps import app_cache +from django.apps import apps from django.core.management import call_command from django.core.management.base import BaseCommand, CommandError from django.core.management.color import no_style @@ -46,7 +46,7 @@ class Command(BaseCommand): # Import the 'management' module within each installed app, to register # dispatcher events. - for app_config in app_cache.get_app_configs(): + for app_config in apps.get_app_configs(): if module_has_submodule(app_config.app_module, "management"): import_module('.management', app_config.name) @@ -135,7 +135,7 @@ class Command(BaseCommand): # If there's changes that aren't in migrations yet, tell them how to fix it. autodetector = MigrationAutodetector( executor.loader.graph.project_state(), - ProjectState.from_app_cache(app_cache), + ProjectState.from_apps(apps), ) changes = autodetector.changes(graph=executor.loader.graph) if changes: @@ -167,8 +167,8 @@ class Command(BaseCommand): else: self.stdout.write(self.style.MIGRATE_SUCCESS(" OK")) - def sync_apps(self, connection, apps): - "Runs the old syncdb-style operation on a list of apps." + def sync_apps(self, connection, app_labels): + "Runs the old syncdb-style operation on a list of app_labels." cursor = connection.cursor() # Get a list of already installed *models* so that references work right. @@ -181,8 +181,8 @@ class Command(BaseCommand): all_models = [ (app_config.label, router.get_migratable_models(app_config.models_module, connection.alias, include_auto_created=True)) - for app_config in app_cache.get_app_configs(only_with_models_module=True) - if app_config.label in apps + for app_config in apps.get_app_configs(only_with_models_module=True) + if app_config.label in app_labels ] def model_installed(model): @@ -277,7 +277,7 @@ class Command(BaseCommand): return created_models - def show_migration_list(self, connection, apps=None): + def show_migration_list(self, connection, app_names=None): """ Shows a list of all migrations on the system, or only those of some named apps. @@ -286,24 +286,24 @@ class Command(BaseCommand): loader = MigrationLoader(connection) graph = loader.graph # If we were passed a list of apps, validate it - if apps: + if app_names: invalid_apps = [] - for app in apps: - if app not in loader.migrated_apps: - invalid_apps.append(app) + for app_name in app_names: + if app_name not in loader.migrated_apps: + invalid_apps.append(app_name) if invalid_apps: raise CommandError("No migrations present for: %s" % (", ".join(invalid_apps))) # Otherwise, show all apps in alphabetic order else: - apps = sorted(loader.migrated_apps) + app_names = sorted(loader.migrated_apps) # For each app, print its migrations in order from oldest (roots) to # newest (leaves). - for app in apps: - self.stdout.write(app, self.style.MIGRATE_LABEL) + for app_name in app_names: + self.stdout.write(app_name, self.style.MIGRATE_LABEL) shown = set() - for node in graph.leaf_nodes(app): + for node in graph.leaf_nodes(app_name): for plan_node in graph.forwards_plan(node): - if plan_node not in shown and plan_node[0] == app: + if plan_node not in shown and plan_node[0] == app_name: # Give it a nice title if it's a squashed one title = plan_node[1] if graph.nodes[plan_node].replaces: diff --git a/django/core/management/commands/shell.py b/django/core/management/commands/shell.py index 12af814161..149b9edd89 100644 --- a/django/core/management/commands/shell.py +++ b/django/core/management/commands/shell.py @@ -66,8 +66,8 @@ class Command(NoArgsCommand): def handle_noargs(self, **options): # XXX: (Temporary) workaround for ticket #1796: force early loading of all # models from installed apps. - from django.apps import app_cache - app_cache.get_models() + from django.apps import apps + apps.get_models() use_plain = options.get('plain', False) no_startup = options.get('no_startup', False) diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py index 24ec25e8ed..58f171e87b 100644 --- a/django/core/management/commands/sqlsequencereset.py +++ b/django/core/management/commands/sqlsequencereset.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from optparse import make_option -from django.apps import app_cache +from django.apps import apps from django.core.management.base import AppCommand from django.db import connections, DEFAULT_DB_ALIAS @@ -21,4 +21,4 @@ class Command(AppCommand): def handle_app(self, app, **options): connection = connections[options.get('database')] - return '\n'.join(connection.ops.sequence_reset_sql(self.style, app_cache.get_models(app, include_auto_created=True))) + return '\n'.join(connection.ops.sequence_reset_sql(self.style, apps.get_models(app, include_auto_created=True))) diff --git a/django/core/management/sql.py b/django/core/management/sql.py index b2500d3787..35ce693e3b 100644 --- a/django/core/management/sql.py +++ b/django/core/management/sql.py @@ -5,7 +5,7 @@ import os import re import warnings -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core.management.base import CommandError from django.db import models, router @@ -25,7 +25,7 @@ def sql_create(app, style, connection): # We trim models from the current app so that the sqlreset command does not # generate invalid SQL (leaving models out of known_models is harmless, so # we can be conservative). - app_models = app_cache.get_models(app, include_auto_created=True) + app_models = apps.get_models(app, include_auto_created=True) final_output = [] tables = connection.introspection.table_names() known_models = set(model for model in connection.introspection.installed_models(tables) if model not in app_models) @@ -169,7 +169,7 @@ def _split_statements(content): def custom_sql_for_model(model, style, connection): opts = model._meta app_dirs = [] - app_dir = app_cache.get_app_config(model._meta.app_label).path + app_dir = apps.get_app_config(model._meta.app_label).path app_dirs.append(os.path.normpath(os.path.join(app_dir, 'sql'))) # Deprecated location -- remove in Django 1.9 @@ -207,7 +207,7 @@ def custom_sql_for_model(model, style, connection): def emit_pre_migrate_signal(create_models, verbosity, interactive, db): # Emit the pre_migrate signal for every application. - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): if verbosity >= 2: print("Running pre-migrate handlers for application %s" % app_config.label) models.signals.pre_migrate.send( @@ -221,7 +221,7 @@ def emit_pre_migrate_signal(create_models, verbosity, interactive, db): def emit_post_migrate_signal(created_models, verbosity, interactive, db): # Emit the post_migrate signal for every application. - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): if verbosity >= 2: print("Running post-migrate handlers for application %s" % app_config.label) models.signals.post_migrate.send( diff --git a/django/core/management/validation.py b/django/core/management/validation.py index 2b27a7edce..c3b55770ce 100644 --- a/django/core/management/validation.py +++ b/django/core/management/validation.py @@ -26,13 +26,13 @@ def get_validation_errors(outfile, app=None): validates all models of all installed apps. Writes errors, if any, to outfile. Returns number of errors. """ - from django.apps import app_cache + from django.apps import apps from django.db import connection, models from django.db.models.deletion import SET_NULL, SET_DEFAULT e = ModelErrorCollection(outfile) - for cls in app_cache.get_models(app, include_swapped=True): + for cls in apps.get_models(app, include_swapped=True): opts = cls._meta # Check swappable attribute. @@ -42,7 +42,7 @@ def get_validation_errors(outfile, app=None): except ValueError: e.add(opts, "%s is not of the form 'app_label.app_name'." % opts.swappable) continue - if not app_cache.get_model(app_label, model_name): + if not apps.get_model(app_label, model_name): e.add(opts, "Model has been swapped out for '%s' which has not been installed or is abstract." % opts.swapped) # No need to perform any other validation checks on a swapped model. continue @@ -152,7 +152,7 @@ def get_validation_errors(outfile, app=None): # Check to see if the related field will clash with any existing # fields, m2m fields, m2m related objects or related objects if f.rel: - if f.rel.to not in app_cache.get_models(): + if f.rel.to not in apps.get_models(): # If the related model is swapped, provide a hint; # otherwise, the model just hasn't been installed. if not isinstance(f.rel.to, six.string_types) and f.rel.to._meta.swapped: @@ -207,7 +207,7 @@ def get_validation_errors(outfile, app=None): # Check to see if the related m2m field will clash with any # existing fields, m2m fields, m2m related objects or related # objects - if f.rel.to not in app_cache.get_models(): + if f.rel.to not in apps.get_models(): # If the related model is swapped, provide a hint; # otherwise, the model just hasn't been installed. if not isinstance(f.rel.to, six.string_types) and f.rel.to._meta.swapped: @@ -265,7 +265,7 @@ def get_validation_errors(outfile, app=None): ) else: seen_to = True - if f.rel.through not in app_cache.get_models(include_auto_created=True): + if f.rel.through not in apps.get_models(include_auto_created=True): e.add(opts, "'%s' specifies an m2m relation through model " "%s, which has not been installed." % (f.name, f.rel.through)) signature = (f.rel.to, cls, f.rel.through) diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index d516656a69..70bc651f82 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -3,7 +3,7 @@ Module for abstract serializer/unserializer base classes. """ import warnings -from django.apps import app_cache +from django.apps import apps from django.db import models from django.utils import six @@ -137,9 +137,9 @@ class Deserializer(six.Iterator): self.stream = six.StringIO(stream_or_string) else: self.stream = stream_or_string - # Make sure the app cache is loaded before deserialization starts + # Make sure the app registy is loaded before deserialization starts # (otherwise subclass calls to get_model() and friends might fail...) - app_cache.populate_models() + apps.populate_models() def __iter__(self): return self diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index c8a2b7eff2..a46adeef7a 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -5,7 +5,7 @@ other serializers. """ from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core.serializers import base from django.db import models, DEFAULT_DB_ALIAS @@ -88,7 +88,7 @@ def Deserializer(object_list, **options): db = options.pop('using', DEFAULT_DB_ALIAS) ignore = options.pop('ignorenonexistent', False) - app_cache.populate_models() + apps.populate_models() for d in object_list: # Look up the model and starting build a dict of data for it. @@ -155,7 +155,7 @@ def _get_model(model_identifier): Helper to look up a model from an "app_label.model_name" string. """ try: - Model = app_cache.get_model(*model_identifier.split(".")) + Model = apps.get_model(*model_identifier.split(".")) except TypeError: Model = None if Model is None: diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py index e9bea84bb1..81e41f8a32 100644 --- a/django/core/serializers/xml_serializer.py +++ b/django/core/serializers/xml_serializer.py @@ -4,7 +4,7 @@ XML serializer. from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core.serializers import base from django.db import models, DEFAULT_DB_ALIAS @@ -277,7 +277,7 @@ class Deserializer(base.Deserializer): "<%s> node is missing the required '%s' attribute" % (node.nodeName, attr)) try: - Model = app_cache.get_model(*model_identifier.split(".")) + Model = apps.get_model(*model_identifier.split(".")) except TypeError: Model = None if Model is None: diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index 86905afe77..c5f650d503 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -1268,10 +1268,10 @@ class BaseDatabaseIntrospection(object): If only_existing is True, the resulting list will only include the tables that actually exist in the database. """ - from django.apps import app_cache + from django.apps import apps from django.db import router tables = set() - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): for model in router.get_migratable_models(app_config.models_module, self.connection.alias): if not model._meta.managed: continue @@ -1289,10 +1289,10 @@ class BaseDatabaseIntrospection(object): def installed_models(self, tables): "Returns a set of all models represented by the provided list of table names." - from django.apps import app_cache + from django.apps import apps from django.db import router all_models = [] - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): all_models.extend(router.get_migratable_models(app_config.models_module, self.connection.alias)) tables = list(map(self.table_name_converter, tables)) return set([ @@ -1302,12 +1302,12 @@ class BaseDatabaseIntrospection(object): def sequence_list(self): "Returns a list of information about all DB sequences for all models in all apps." - from django.apps import app_cache + from django.apps import apps from django.db import models, router sequence_list = [] - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): for model in router.get_migratable_models(app_config.models_module, self.connection.alias): if not model._meta.managed: continue diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py index 52ca2de8ed..3196b48946 100644 --- a/django/db/backends/sqlite3/schema.py +++ b/django/db/backends/sqlite3/schema.py @@ -1,4 +1,4 @@ -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.db.backends.schema import BaseDatabaseSchemaEditor from django.db.models.fields.related import ManyToManyField @@ -38,14 +38,14 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): for field in delete_fields: del body[field.name] del mapping[field.column] - # Work inside a new AppCache - app_cache = AppCache() + # Work inside a new app registry + apps = Apps() # Construct a new model for the new state meta_contents = { 'app_label': model._meta.app_label, 'db_table': model._meta.db_table + "__new", 'unique_together': model._meta.unique_together if override_uniques is None else override_uniques, - 'app_cache': app_cache, + 'apps': apps, } meta = type("Meta", tuple(), meta_contents) body['Meta'] = meta diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index 4074366188..f71d193960 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -47,19 +47,19 @@ class MigrationAutodetector(object): """ # We'll store migrations as lists by app names for now self.migrations = {} - old_app_cache = self.from_state.render() - new_app_cache = self.to_state.render() + old_apps = self.from_state.render() + new_apps = self.to_state.render() # Prepare lists of old/new model keys that we care about # (i.e. ignoring proxy ones) old_model_keys = [ (al, mn) for al, mn in self.from_state.models.keys() - if not old_app_cache.get_model(al, mn)._meta.proxy + if not old_apps.get_model(al, mn)._meta.proxy ] new_model_keys = [ (al, mn) for al, mn in self.to_state.models.keys() - if not new_app_cache.get_model(al, mn)._meta.proxy + if not new_apps.get_model(al, mn)._meta.proxy ] # Adding models. Phase 1 is adding models with no outward relationships. added_models = set(new_model_keys) - set(old_model_keys) @@ -68,7 +68,7 @@ class MigrationAutodetector(object): model_state = self.to_state.models[app_label, model_name] # Are there any relationships out from this model? if so, punt it to the next phase. related_fields = [] - for field in new_app_cache.get_model(app_label, model_name)._meta.local_fields: + for field in new_apps.get_model(app_label, model_name)._meta.local_fields: if field.rel: if field.rel.to: related_fields.append((field.name, field.rel.to._meta.app_label.lower(), field.rel.to._meta.object_name.lower())) diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py index 26d269fd9f..9ecdf771e3 100644 --- a/django/db/migrations/executor.py +++ b/django/db/migrations/executor.py @@ -129,10 +129,10 @@ class MigrationExecutor(object): on initial migrations (as it only looks for CreateModel). """ project_state = self.loader.graph.project_state((migration.app_label, migration.name), at_end=True) - app_cache = project_state.render() + apps = project_state.render() for operation in migration.operations: if isinstance(operation, migrations.CreateModel): - model = app_cache.get_model(migration.app_label, operation.name) + model = apps.get_model(migration.app_label, operation.name) if model._meta.db_table not in self.connection.introspection.get_table_list(self.connection.cursor()): return False return True diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 9a54f14e75..d24f7ab889 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -2,7 +2,7 @@ from importlib import import_module import os import sys -from django.apps import app_cache +from django.apps import apps from django.db.migrations.recorder import MigrationRecorder from django.db.migrations.graph import MigrationGraph from django.utils import six @@ -46,7 +46,7 @@ class MigrationLoader(object): if app_label in settings.MIGRATION_MODULES: return settings.MIGRATION_MODULES[app_label] else: - return '%s.migrations' % app_cache.get_app_config(app_label).name + return '%s.migrations' % apps.get_app_config(app_label).name def load_disk(self): """ @@ -55,7 +55,7 @@ class MigrationLoader(object): self.disk_migrations = {} self.unmigrated_apps = set() self.migrated_apps = set() - for app_config in app_cache.get_app_configs(only_with_models_module=True): + for app_config in apps.get_app_configs(only_with_models_module=True): # Get the migrations module directory module_name = self.migrations_module(app_config.label) was_loaded = module_name in sys.modules diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py index 8c7fe126a8..1aefbd9457 100644 --- a/django/db/migrations/operations/models.py +++ b/django/db/migrations/operations/models.py @@ -20,14 +20,14 @@ class CreateModel(Operation): state.models[app_label, self.name.lower()] = ModelState(app_label, self.name, self.fields, self.options, self.bases) def database_forwards(self, app_label, schema_editor, from_state, to_state): - app_cache = to_state.render() - model = app_cache.get_model(app_label, self.name) + apps = to_state.render() + model = apps.get_model(app_label, self.name) if router.allow_migrate(schema_editor.connection.alias, model): schema_editor.create_model(model) def database_backwards(self, app_label, schema_editor, from_state, to_state): - app_cache = from_state.render() - model = app_cache.get_model(app_label, self.name) + apps = from_state.render() + model = apps.get_model(app_label, self.name) if router.allow_migrate(schema_editor.connection.alias, model): schema_editor.delete_model(model) @@ -73,14 +73,14 @@ class DeleteModel(Operation): del state.models[app_label, self.name.lower()] def database_forwards(self, app_label, schema_editor, from_state, to_state): - app_cache = from_state.render() - model = app_cache.get_model(app_label, self.name) + apps = from_state.render() + model = apps.get_model(app_label, self.name) if router.allow_migrate(schema_editor.connection.alias, model): schema_editor.delete_model(model) def database_backwards(self, app_label, schema_editor, from_state, to_state): - app_cache = to_state.render() - model = app_cache.get_model(app_label, self.name) + apps = to_state.render() + model = apps.get_model(app_label, self.name) if router.allow_migrate(schema_editor.connection.alias, model): schema_editor.create_model(model) @@ -106,10 +106,10 @@ class RenameModel(Operation): del state.models[app_label, self.old_name.lower()] def database_forwards(self, app_label, schema_editor, from_state, to_state): - old_app_cache = from_state.render() - new_app_cache = to_state.render() - old_model = old_app_cache.get_model(app_label, self.old_name) - new_model = new_app_cache.get_model(app_label, self.new_name) + old_apps = from_state.render() + new_apps = to_state.render() + old_model = old_apps.get_model(app_label, self.old_name) + new_model = new_apps.get_model(app_label, self.new_name) if router.allow_migrate(schema_editor.connection.alias, new_model): schema_editor.alter_db_table( new_model, @@ -118,10 +118,10 @@ class RenameModel(Operation): ) def database_backwards(self, app_label, schema_editor, from_state, to_state): - old_app_cache = from_state.render() - new_app_cache = to_state.render() - old_model = old_app_cache.get_model(app_label, self.new_name) - new_model = new_app_cache.get_model(app_label, self.old_name) + old_apps = from_state.render() + new_apps = to_state.render() + old_model = old_apps.get_model(app_label, self.new_name) + new_model = new_apps.get_model(app_label, self.old_name) if router.allow_migrate(schema_editor.connection.alias, new_model): schema_editor.alter_db_table( new_model, @@ -152,10 +152,10 @@ class AlterModelTable(Operation): state.models[app_label, self.name.lower()].options["db_table"] = self.table def database_forwards(self, app_label, schema_editor, from_state, to_state): - old_app_cache = from_state.render() - new_app_cache = to_state.render() - old_model = old_app_cache.get_model(app_label, self.name) - new_model = new_app_cache.get_model(app_label, self.name) + old_apps = from_state.render() + new_apps = to_state.render() + old_model = old_apps.get_model(app_label, self.name) + new_model = new_apps.get_model(app_label, self.name) if router.allow_migrate(schema_editor.connection.alias, new_model): schema_editor.alter_db_table( new_model, @@ -189,10 +189,10 @@ class AlterUniqueTogether(Operation): model_state.options["unique_together"] = self.unique_together def database_forwards(self, app_label, schema_editor, from_state, to_state): - old_app_cache = from_state.render() - new_app_cache = to_state.render() - old_model = old_app_cache.get_model(app_label, self.name) - new_model = new_app_cache.get_model(app_label, self.name) + old_apps = from_state.render() + new_apps = to_state.render() + old_model = old_apps.get_model(app_label, self.name) + new_model = new_apps.get_model(app_label, self.name) if router.allow_migrate(schema_editor.connection.alias, new_model): schema_editor.alter_unique_together( new_model, @@ -225,10 +225,10 @@ class AlterIndexTogether(Operation): model_state.options["index_together"] = self.index_together def database_forwards(self, app_label, schema_editor, from_state, to_state): - old_app_cache = from_state.render() - new_app_cache = to_state.render() - old_model = old_app_cache.get_model(app_label, self.name) - new_model = new_app_cache.get_model(app_label, self.name) + old_apps = from_state.render() + new_apps = to_state.render() + old_model = old_apps.get_model(app_label, self.name) + new_model = new_apps.get_model(app_label, self.name) if router.allow_migrate(schema_editor.connection.alias, new_model): schema_editor.alter_index_together( new_model, diff --git a/django/db/migrations/operations/special.py b/django/db/migrations/operations/special.py index f48d8cab05..65fd8125fc 100644 --- a/django/db/migrations/operations/special.py +++ b/django/db/migrations/operations/special.py @@ -134,7 +134,7 @@ class RunPython(Operation): def database_forwards(self, app_label, schema_editor, from_state, to_state): # We now execute the Python code in a context that contains a 'models' - # object, representing the versioned models as an AppCache. + # object, representing the versioned models as an app registry. # We could try to override the global cache, but then people will still # use direct imports, so we go with a documentation approach instead. if callable(self.code): diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index 4a860dcf7e..efd75189ef 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -2,7 +2,7 @@ import importlib import os import sys -from django.apps import app_cache +from django.apps import apps from django.utils import datetime_safe from django.utils.six.moves import input @@ -28,7 +28,7 @@ class MigrationQuestioner(object): # Apps from the new app template will have these; the python # file check will ensure we skip South ones. try: - app_config = app_cache.get_app_config(app_label) + app_config = apps.get_app_config(app_label) except LookupError: # It's a fake app. return self.defaults.get("ask_initial", False) migrations_import_path = "%s.migrations" % app_config.name diff --git a/django/db/migrations/recorder.py b/django/db/migrations/recorder.py index 8b0403e88f..15a3b49578 100644 --- a/django/db/migrations/recorder.py +++ b/django/db/migrations/recorder.py @@ -1,4 +1,4 @@ -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.db import models from django.utils.timezone import now @@ -22,7 +22,7 @@ class MigrationRecorder(object): applied = models.DateTimeField(default=now) class Meta: - app_cache = AppCache() + apps = Apps() app_label = "migrations" db_table = "django_migrations" diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index a2716e864a..198b2c516c 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -1,4 +1,4 @@ -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.db import models from django.db.models.options import DEFAULT_NAMES, normalize_unique_together from django.utils import six @@ -18,7 +18,7 @@ class ProjectState(object): def __init__(self, models=None): self.models = models or {} - self.app_cache = None + self.apps = None def add_model_state(self, model_state): self.models[(model_state.app_label, model_state.name.lower())] = model_state @@ -30,9 +30,9 @@ class ProjectState(object): ) def render(self): - "Turns the project state into actual models in a new AppCache" - if self.app_cache is None: - self.app_cache = AppCache() + "Turns the project state into actual models in a new Apps" + if self.apps is None: + self.apps = Apps() # We keep trying to render the models in a loop, ignoring invalid # base errors, until the size of the unrendered models doesn't # decrease by at least one, meaning there's a base dependency loop/ @@ -42,19 +42,19 @@ class ProjectState(object): new_unrendered_models = [] for model in unrendered_models: try: - model.render(self.app_cache) + model.render(self.apps) except InvalidBasesError: new_unrendered_models.append(model) if len(new_unrendered_models) == len(unrendered_models): raise InvalidBasesError("Cannot resolve bases for %r" % new_unrendered_models) unrendered_models = new_unrendered_models - return self.app_cache + return self.apps @classmethod - def from_app_cache(cls, app_cache): - "Takes in an AppCache and returns a ProjectState matching it" + def from_apps(cls, apps): + "Takes in an Apps and returns a ProjectState matching it" app_models = {} - for model in app_cache.get_models(): + for model in apps.get_models(): model_state = ModelState.from_model(model) app_models[(model_state.app_label, model_state.name.lower())] = model_state return cls(app_models) @@ -123,7 +123,7 @@ class ModelState(object): options = {} for name in DEFAULT_NAMES: # Ignore some special options - if name in ["app_cache", "app_label"]: + if name in ["apps", "app_label"]: continue elif name in model._meta.original_attrs: if name == "unique_together": @@ -164,17 +164,17 @@ class ModelState(object): bases=self.bases, ) - def render(self, app_cache): - "Creates a Model object from our current state into the given app_cache" + def render(self, apps): + "Creates a Model object from our current state into the given apps" # First, make a Meta object - meta_contents = {'app_label': self.app_label, "app_cache": app_cache} + meta_contents = {'app_label': self.app_label, "apps": apps} meta_contents.update(self.options) if "unique_together" in meta_contents: meta_contents["unique_together"] = list(meta_contents["unique_together"]) meta = type("Meta", tuple(), meta_contents) # Then, work out our bases bases = tuple( - (app_cache.get_model(*base.split(".", 1)) if isinstance(base, six.string_types) else base) + (apps.get_model(*base.split(".", 1)) if isinstance(base, six.string_types) else base) for base in self.bases ) if None in bases: diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py index a23a9b1253..549c72ed60 100644 --- a/django/db/migrations/writer.py +++ b/django/db/migrations/writer.py @@ -5,7 +5,7 @@ from importlib import import_module import os import types -from django.apps import app_cache +from django.apps import apps from django.db import models from django.db.migrations.loader import MigrationLoader from django.utils.encoding import force_text @@ -69,7 +69,7 @@ class MigrationWriter(object): migrations_module = import_module(migrations_package_name) basedir = os.path.dirname(migrations_module.__file__) except ImportError: - app_config = app_cache.get_app_config(self.migration.app_label) + app_config = apps.get_app_config(self.migration.app_label) migrations_package_basename = migrations_package_name.split(".")[-1] # Alright, see if it's a direct submodule of the app diff --git a/django/db/models/base.py b/django/db/models/base.py index 85e4be870b..66c1d96762 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -5,7 +5,7 @@ import sys from functools import update_wrapper from django.utils.six.moves import zip -from django.apps import app_cache +from django.apps import apps from django.apps.base import MODELS_MODULE_NAME import django.db.models.manager # NOQA: Imported to register signal handler. from django.conf import settings @@ -151,7 +151,7 @@ class ModelBase(type): new_class._base_manager = new_class._base_manager._copy_to_model(new_class) # Bail out early if we have already created this class. - m = new_class._meta.app_cache.get_registered_model(new_class._meta.app_label, name) + m = new_class._meta.apps.get_registered_model(new_class._meta.app_label, name) if m is not None: return m @@ -273,12 +273,12 @@ class ModelBase(type): new_class._prepare() - new_class._meta.app_cache.register_model(new_class._meta.app_label, new_class) + new_class._meta.apps.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 # registered version. - return new_class._meta.app_cache.get_registered_model(new_class._meta.app_label, name) + return new_class._meta.apps.get_registered_model(new_class._meta.app_label, name) def copy_managers(cls, base_managers): # This is in-place sorting of an Options attribute, but that's fine. @@ -1065,7 +1065,7 @@ def model_unpickle(model_id, attrs, factory): Used to unpickle Model subclasses with deferred fields. """ if isinstance(model_id, tuple): - model = app_cache.get_model(*model_id) + model = apps.get_model(*model_id) else: # Backwards compat - the model was cached directly in earlier versions. model = model_id diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 830ff2efa2..6dcfd9ca70 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -9,7 +9,7 @@ import warnings from base64 import b64decode, b64encode from itertools import tee -from django.apps import app_cache +from django.apps import apps from django.db import connection from django.db.models.query_utils import QueryWrapper from django.conf import settings @@ -51,7 +51,7 @@ BLANK_CHOICE_DASH = [("", "---------")] def _load_field(app_label, model_name, field_name): - return app_cache.get_model(app_label, model_name)._meta.get_field_by_name(field_name)[0] + return apps.get_model(app_label, model_name)._meta.get_field_by_name(field_name)[0] class FieldDoesNotExist(Exception): @@ -287,7 +287,7 @@ class Field(object): def __reduce__(self): """ Pickling should return the model._meta.fields instance of the field, - not a new copy of that field. So, we use the app cache to load the + not a new copy of that field. So, we use the app registry to load the model and then the field back. """ if not hasattr(self, 'model'): @@ -298,8 +298,8 @@ class Field(object): # values - so, this is very close to normal pickle. return _empty, (self.__class__,), self.__dict__ if self.model._deferred: - # Deferred model will not be found from the app cache. This could - # be fixed by reconstructing the deferred model on unpickle. + # Deferred model will not be found from the app registry. This + # could be fixed by reconstructing the deferred model on unpickle. raise RuntimeError("Fields of deferred models can't be reduced") return _load_field, (self.model._meta.app_label, self.model._meta.object_name, self.name) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index d6d84e1b23..769121bc01 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -68,13 +68,13 @@ def add_lazy_relation(cls, field, relation, operation): # string right away. If get_model returns None, it means that the related # model isn't loaded yet, so we need to pend the relation until the class # is prepared. - model = cls._meta.app_cache.get_registered_model(app_label, model_name) + model = cls._meta.apps.get_registered_model(app_label, model_name) if model: operation(field, model, cls) else: key = (app_label, model_name) value = (cls, field, operation) - cls._meta.app_cache._pending_lookups.setdefault(key, []).append(value) + cls._meta.apps._pending_lookups.setdefault(key, []).append(value) def do_pending_lookups(sender, **kwargs): @@ -82,7 +82,7 @@ def do_pending_lookups(sender, **kwargs): Handle any pending relations to the sending model. Sent from class_prepared. """ key = (sender._meta.app_label, sender.__name__) - for cls, field, operation in sender._meta.app_cache._pending_lookups.pop(key, []): + for cls, field, operation in sender._meta.apps._pending_lookups.pop(key, []): operation(field, sender, cls) signals.class_prepared.connect(do_pending_lookups) @@ -1493,7 +1493,7 @@ def create_many_to_many_intermediary_model(field, klass): 'unique_together': (from_, to), 'verbose_name': '%(from)s-%(to)s relationship' % {'from': from_, 'to': to}, 'verbose_name_plural': '%(from)s-%(to)s relationships' % {'from': from_, 'to': to}, - 'app_cache': field.model._meta.app_cache, + 'apps': field.model._meta.apps, }) # Construct and return the new class. return type(str(name), (models.Model,), { diff --git a/django/db/models/loading.py b/django/db/models/loading.py index 4b58ba00b5..42fcce8551 100644 --- a/django/db/models/loading.py +++ b/django/db/models/loading.py @@ -1,6 +1,6 @@ import warnings -from django.apps import app_cache +from django.apps import apps warnings.warn( "The utilities in django.db.models.loading are deprecated " @@ -12,24 +12,24 @@ __all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models', # These methods were always module level, so are kept that way for backwards # compatibility. -get_apps = app_cache.get_apps -get_app_package = app_cache.get_app_package -get_app_path = app_cache.get_app_path -get_app_paths = app_cache.get_app_paths -get_app = app_cache.get_app -get_models = app_cache.get_models -get_model = app_cache.get_model -register_models = app_cache.register_models -load_app = app_cache.load_app -app_cache_ready = app_cache.app_cache_ready +get_apps = apps.get_apps +get_app_package = apps.get_app_package +get_app_path = apps.get_app_path +get_app_paths = apps.get_app_paths +get_app = apps.get_app +get_models = apps.get_models +get_model = apps.get_model +register_models = apps.register_models +load_app = apps.load_app +app_cache_ready = apps.ready # This method doesn't return anything interesting in Django 1.6. Maintain it # just for backwards compatibility until this module is deprecated. def get_app_errors(): try: - return app_cache.app_errors + return apps.app_errors except AttributeError: - app_cache.populate_models() - app_cache.app_errors = {} - return app_cache.app_errors + apps.populate_models() + apps.app_errors = {} + return apps.app_errors diff --git a/django/db/models/options.py b/django/db/models/options.py index 8f181c8854..1186d3b50a 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -5,7 +5,7 @@ import re from bisect import bisect import warnings -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.db.models.fields.related import ManyToManyRel from django.db.models.fields import AutoField, FieldDoesNotExist @@ -22,7 +22,7 @@ DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering', 'unique_together', 'permissions', 'get_latest_by', 'order_with_respect_to', 'app_label', 'db_tablespace', 'abstract', 'managed', 'proxy', 'swappable', 'auto_created', - 'index_together', 'app_cache', 'default_permissions', + 'index_together', 'apps', 'default_permissions', 'select_on_save') @@ -88,13 +88,13 @@ class Options(object): # from *other* models. Needed for some admin checks. Internal use only. self.related_fkey_lookups = [] - # A custom AppCache to use, if you're making a separate model set. - self.app_cache = app_cache + # A custom app registry to use, if you're making a separate model set. + self.apps = apps @property def app_config(self): # Don't go through get_app_config to avoid triggering imports. - return self.app_cache.app_configs.get(self.app_label) + return self.apps.app_configs.get(self.app_label) @property def installed(self): @@ -440,7 +440,7 @@ class Options(object): if hasattr(f, 'related'): cache[f.name] = cache[f.attname] = ( f.related, None if f.model == self.model else f.model, True, False) - if app_cache.app_cache_ready(): + if apps.ready(): self._name_map = cache return cache @@ -516,7 +516,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.app_cache.get_models(include_auto_created=True, only_installed=False): + for klass in self.apps.get_models(include_auto_created=True, only_installed=False): 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: @@ -559,14 +559,14 @@ class Options(object): cache[obj] = parent else: cache[obj] = model - for klass in self.app_cache.get_models(only_installed=False): + for klass in self.apps.get_models(only_installed=False): if not klass._meta.swapped: for f in klass._meta.local_many_to_many: if (f.rel and not isinstance(f.rel.to, six.string_types) and self == f.rel.to._meta): cache[f.related] = None - if app_cache.app_cache_ready(): + if apps.ready(): self._related_many_to_many_cache = cache return cache diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py index a7d98f60fe..2aa4856cf0 100644 --- a/django/db/models/query_utils.py +++ b/django/db/models/query_utils.py @@ -189,9 +189,9 @@ def deferred_class_factory(model, attrs): proxy = True app_label = model._meta.app_label - # The app_cache wants a unique name for each model, otherwise the new class - # won't be created (we get an old one back). Therefore, we generate the - # name using the passed in attrs. It's OK to reuse an existing class + # The app registry wants a unique name for each model, otherwise the new + # class won't be created (we get an old one back). Therefore, we generate + # the name using the passed in attrs. It's OK to reuse an existing class # object if the attrs are identical. name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(list(attrs)))) name = utils.truncate_name(name, 80, 32) diff --git a/django/db/models/signals.py b/django/db/models/signals.py index 8c835e5f5f..10da3e22a5 100644 --- a/django/db/models/signals.py +++ b/django/db/models/signals.py @@ -1,6 +1,6 @@ from collections import defaultdict -from django.apps import app_cache +from django.apps import apps from django.dispatch import Signal from django.utils import six @@ -41,7 +41,7 @@ class ModelSignal(Signal): "Specified sender must either be a model or a " "model name of the 'app_label.ModelName' form." ) - sender = app_cache.get_model(app_label, object_name, only_installed=False) + sender = apps.get_model(app_label, object_name, only_installed=False) if sender is None: reference = (app_label, object_name) self.unresolved_references[reference].append( diff --git a/django/db/utils.py b/django/db/utils.py index 702b1b4ebc..85eabb934e 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -282,6 +282,6 @@ class ConnectionRouter(object): """ Return app models allowed to be synchronized on provided db. """ - from django.apps import app_cache - return [model for model in app_cache.get_models(app, include_auto_created=include_auto_created) + from django.apps import apps + return [model for model in apps.get_models(app, include_auto_created=include_auto_created) if self.allow_migrate(db, model)] diff --git a/django/template/base.py b/django/template/base.py index 197238b1e3..883609cf3e 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -5,7 +5,7 @@ from functools import partial from importlib import import_module from inspect import getargspec, getcallargs -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.template.context import (BaseContext, Context, RequestContext, # NOQA: imported for backwards compatibility ContextPopException) @@ -1306,7 +1306,7 @@ def get_templatetags_modules(): templatetags_modules_candidates = ['django.templatetags'] templatetags_modules_candidates += ['%s.templatetags' % app_config.name - for app_config in app_cache.get_app_configs()] + for app_config in apps.get_app_configs()] for templatetag_module in templatetags_modules_candidates: try: import_module(templatetag_module) diff --git a/django/template/loaders/app_directories.py b/django/template/loaders/app_directories.py index ff3d3b93f8..a2e741b419 100644 --- a/django/template/loaders/app_directories.py +++ b/django/template/loaders/app_directories.py @@ -6,7 +6,7 @@ packages. import os import sys -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.template.base import TemplateDoesNotExist from django.template.loader import BaseLoader @@ -17,7 +17,7 @@ from django.utils import six if six.PY2: fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() app_template_dirs = [] -for app_config in app_cache.get_app_configs(): +for app_config in apps.get_app_configs(): template_dir = os.path.join(app_config.path, 'templates') if os.path.isdir(template_dir): if six.PY2: diff --git a/django/template/loaders/eggs.py b/django/template/loaders/eggs.py index 99c19aed93..bb49b302c9 100644 --- a/django/template/loaders/eggs.py +++ b/django/template/loaders/eggs.py @@ -6,7 +6,7 @@ try: except ImportError: resource_string = None -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.template.base import TemplateDoesNotExist from django.template.loader import BaseLoader @@ -24,7 +24,7 @@ class Loader(BaseLoader): """ if resource_string is not None: pkg_name = 'templates/' + template_name - for app_config in app_cache.get_app_configs(): + for app_config in apps.get_app_configs(): try: resource = resource_string(app_config.name, pkg_name) except Exception: diff --git a/django/test/client.py b/django/test/client.py index eea9b43010..a2da8bcd38 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -8,7 +8,7 @@ from copy import copy from importlib import import_module from io import BytesIO -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.contrib.auth import authenticate, login, logout, get_user_model from django.core.handlers.base import BaseHandler @@ -390,7 +390,7 @@ class Client(RequestFactory): """ Obtains the current session variables. """ - if app_cache.has_app('django.contrib.sessions'): + if apps.has_app('django.contrib.sessions'): engine = import_module(settings.SESSION_ENGINE) cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None) if cookie: @@ -551,7 +551,7 @@ class Client(RequestFactory): """ user = authenticate(**credentials) if (user and user.is_active and - app_cache.has_app('django.contrib.sessions')): + apps.has_app('django.contrib.sessions')): engine = import_module(settings.SESSION_ENGINE) # Create a fake request that goes through request middleware diff --git a/django/test/simple.py b/django/test/simple.py index f2d26376df..fa70738447 100644 --- a/django/test/simple.py +++ b/django/test/simple.py @@ -9,7 +9,7 @@ import re import unittest as real_unittest import warnings -from django.apps import app_cache +from django.apps import apps from django.test import _doctest as doctest from django.test import runner from django.test.utils import compare_xml, strip_quotes @@ -168,7 +168,7 @@ def build_test(label): raise ValueError("Test label '%s' should be of the form app.TestCase " "or app.TestCase.test_method" % label) - app_config = app_cache.get_app_config(parts[0]) + app_config = apps.get_app_config(parts[0]) models_module = app_config.models_module tests_module = get_tests(app_config) @@ -237,10 +237,10 @@ class DjangoTestSuiteRunner(runner.DiscoverRunner): if '.' in label: suite.addTest(build_test(label)) else: - app_config = app_cache.get_app_config(label) + app_config = apps.get_app_config(label) suite.addTest(build_suite(app_config)) else: - for app_config in app_cache.get_app_configs(): + for app_config in apps.get_app_configs(): suite.addTest(build_suite(app_config)) if extra_tests: diff --git a/django/test/testcases.py b/django/test/testcases.py index 0e1bb78d46..056eb5469f 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -15,7 +15,7 @@ import unittest from unittest import skipIf # NOQA: Imported here for backward compatibility from unittest.util import safe_repr -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core import mail from django.core.exceptions import ValidationError, ImproperlyConfigured @@ -732,13 +732,13 @@ class TransactionTestCase(SimpleTestCase): """Performs any pre-test setup. This includes: * If the class has an 'available_apps' attribute, restricting the app - cache to these applications, then firing post_migrate -- it must run - with the correct set of applications for the test case. + registry to these applications, then firing post_migrate -- it must + run with the correct set of applications for the test case. * If the class has a 'fixtures' attribute, installing these fixtures. """ super(TransactionTestCase, self)._pre_setup() if self.available_apps is not None: - app_cache.set_available_apps(self.available_apps) + apps.set_available_apps(self.available_apps) setting_changed.send(sender=settings._wrapped.__class__, setting='INSTALLED_APPS', value=self.available_apps, @@ -749,7 +749,7 @@ class TransactionTestCase(SimpleTestCase): self._fixture_setup() except Exception: if self.available_apps is not None: - app_cache.unset_available_apps() + apps.unset_available_apps() setting_changed.send(sender=settings._wrapped.__class__, setting='INSTALLED_APPS', value=settings.INSTALLED_APPS, @@ -809,7 +809,7 @@ class TransactionTestCase(SimpleTestCase): conn.close() finally: if self.available_apps is not None: - app_cache.unset_available_apps() + apps.unset_available_apps() setting_changed.send(sender=settings._wrapped.__class__, setting='INSTALLED_APPS', value=settings.INSTALLED_APPS, diff --git a/django/test/utils.py b/django/test/utils.py index 4453545dea..42cb127129 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -9,7 +9,7 @@ import warnings from functools import wraps from xml.dom.minidom import parseString, Node -from django.apps import app_cache +from django.apps import apps from django.conf import settings, UserSettingsHolder from django.core import mail from django.core.signals import request_started @@ -229,9 +229,9 @@ class override_settings(object): # in case it raises an exception because INSTALLED_APPS is invalid. if 'INSTALLED_APPS' in self.options: try: - app_cache.set_installed_apps(self.options['INSTALLED_APPS']) + apps.set_installed_apps(self.options['INSTALLED_APPS']) except Exception: - app_cache.unset_installed_apps() + apps.unset_installed_apps() raise override = UserSettingsHolder(settings._wrapped) for key, new_value in self.options.items(): @@ -244,7 +244,7 @@ class override_settings(object): def disable(self): if 'INSTALLED_APPS' in self.options: - app_cache.unset_installed_apps() + apps.unset_installed_apps() settings._wrapped = self.wrapped del self.wrapped for key in self.options: diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index b7a889aa61..94c74e582a 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -36,7 +36,7 @@ import sys import time import traceback -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.core.signals import request_finished try: @@ -90,7 +90,7 @@ def gen_filenames(): basedirs = [os.path.join(os.path.dirname(os.path.dirname(__file__)), 'conf', 'locale'), 'locale'] - for app_config in reversed(list(app_cache.get_app_configs())): + for app_config in reversed(list(apps.get_app_configs())): basedirs.append(os.path.join(app_config.path, 'locale')) basedirs.extend(settings.LOCALE_PATHS) basedirs = [os.path.abspath(basedir) for basedir in basedirs diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index c7826be5e5..1ed7d93e31 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -58,10 +58,10 @@ def autodiscover_modules(*args, **kwargs): registry. This register_to object must have a _registry instance variable to access it. """ - from django.apps import app_cache + from django.apps import apps register_to = kwargs.get('register_to') - for app_config in app_cache.get_app_configs(): + for app_config in apps.get_app_configs(): # Attempt to import the app's module. try: if register_to: diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index 1eced98d31..29c133006e 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -10,7 +10,7 @@ import gettext as gettext_module from threading import local import warnings -from django.apps import app_cache +from django.apps import apps from django.dispatch import receiver from django.test.signals import setting_changed from django.utils.encoding import force_str, force_text @@ -179,7 +179,7 @@ def translation(language): res.merge(t) return res - for app_config in reversed(list(app_cache.get_app_configs())): + for app_config in reversed(list(apps.get_app_configs())): apppath = os.path.join(app_config.path, 'locale') if os.path.isdir(apppath): res = _merge(apppath) diff --git a/django/views/i18n.py b/django/views/i18n.py index 2cc2e35e5e..7182f4f3cd 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -4,7 +4,7 @@ import os import gettext as gettext_module from django import http -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.template import Context, Template from django.utils.translation import check_for_language, to_locale, get_language @@ -188,7 +188,7 @@ def render_javascript_catalog(catalog=None, plural=None): def get_javascript_catalog(locale, domain, packages): default_locale = to_locale(settings.LANGUAGE_CODE) - app_configs = app_cache.get_app_configs() + app_configs = apps.get_app_configs() allowable_packages = set(app_config.name for app_config in app_configs) allowable_packages.add('django.conf') packages = [p for p in packages if p in allowable_packages] diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index ef2561a05d..29a68ff0c1 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -222,9 +222,7 @@ these changes. * ``django.core.cache.get_cache`` will be removed. Add suitable entries to :setting:`CACHES` and use :data:`django.core.cache.caches` instead. -* ``django.db.models.loading`` will be removed. Use the new application - loading APIs instead. Several undocumented methods of the ``AppCache`` class - will also be removed. +* ``django.db.models.loading`` will be removed. * Passing callable arguments to querysets will no longer be possible. diff --git a/tests/app_cache/tests.py b/tests/app_cache/tests.py deleted file mode 100644 index 43133ab38f..0000000000 --- a/tests/app_cache/tests.py +++ /dev/null @@ -1,51 +0,0 @@ -from __future__ import absolute_import - -from django.apps import app_cache -from django.apps.cache import AppCache -from django.db import models -from django.test import TestCase - -from .models import TotallyNormal, SoAlternative, new_app_cache - - -class AppCacheTests(TestCase): - - def test_models_py(self): - """ - Tests that the models in the models.py file were loaded correctly. - """ - self.assertEqual(app_cache.get_model("app_cache", "TotallyNormal"), TotallyNormal) - self.assertEqual(app_cache.get_model("app_cache", "SoAlternative"), None) - - self.assertEqual(new_app_cache.get_model("app_cache", "TotallyNormal"), None) - self.assertEqual(new_app_cache.get_model("app_cache", "SoAlternative"), SoAlternative) - - def test_dynamic_load(self): - """ - Makes a new model at runtime and ensures it goes into the right place. - """ - old_models = app_cache.get_models(app_cache.get_app_config("app_cache").models_module) - # Construct a new model in a new app cache - body = {} - new_app_cache = AppCache() - meta_contents = { - 'app_label': "app_cache", - 'app_cache': new_app_cache, - } - meta = type("Meta", tuple(), meta_contents) - body['Meta'] = meta - body['__module__'] = TotallyNormal.__module__ - temp_model = type("SouthPonies", (models.Model,), body) - # Make sure it appeared in the right place! - self.assertEqual( - old_models, - app_cache.get_models(app_cache.get_app_config("app_cache").models_module), - ) - self.assertEqual(new_app_cache.get_model("app_cache", "SouthPonies"), temp_model) - - def test_singleton_master(self): - """ - Ensures that only one master app cache can exist. - """ - with self.assertRaises(RuntimeError): - AppCache(master=True) diff --git a/tests/app_loading/tests.py b/tests/app_loading/tests.py index 291877108f..19a1d03d74 100644 --- a/tests/app_loading/tests.py +++ b/tests/app_loading/tests.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import os import sys -from django.apps import app_cache +from django.apps import apps from django.test import TestCase from django.utils._os import upath from django.utils import six @@ -17,11 +17,11 @@ class EggLoadingTest(TestCase): # The models need to be removed after the test in order to prevent bad # interactions with the flush operation in other tests. - self._old_models = app_cache.all_models['app_loading'].copy() + self._old_models = apps.all_models['app_loading'].copy() def tearDown(self): - app_cache.all_models['app_loading'] = self._old_models - app_cache.get_models.cache_clear() + apps.all_models['app_loading'] = self._old_models + apps.get_models.cache_clear() sys.path = self.old_path @@ -30,7 +30,7 @@ class EggLoadingTest(TestCase): egg_name = '%s/modelapp.egg' % self.egg_dir sys.path.append(egg_name) with self.settings(INSTALLED_APPS=['app_with_models']): - models_module = app_cache.get_app_config('app_with_models').models_module + models_module = apps.get_app_config('app_with_models').models_module self.assertIsNotNone(models_module) def test_egg2(self): @@ -38,7 +38,7 @@ class EggLoadingTest(TestCase): egg_name = '%s/nomodelapp.egg' % self.egg_dir sys.path.append(egg_name) with self.settings(INSTALLED_APPS=['app_no_models']): - models_module = app_cache.get_app_config('app_no_models').models_module + models_module = apps.get_app_config('app_no_models').models_module self.assertIsNone(models_module) def test_egg3(self): @@ -46,7 +46,7 @@ class EggLoadingTest(TestCase): egg_name = '%s/omelet.egg' % self.egg_dir sys.path.append(egg_name) with self.settings(INSTALLED_APPS=['omelet.app_with_models']): - models_module = app_cache.get_app_config('app_with_models').models_module + models_module = apps.get_app_config('app_with_models').models_module self.assertIsNotNone(models_module) def test_egg4(self): @@ -54,7 +54,7 @@ class EggLoadingTest(TestCase): egg_name = '%s/omelet.egg' % self.egg_dir sys.path.append(egg_name) with self.settings(INSTALLED_APPS=['omelet.app_no_models']): - models_module = app_cache.get_app_config('app_no_models').models_module + models_module = apps.get_app_config('app_no_models').models_module self.assertIsNone(models_module) def test_egg5(self): @@ -73,26 +73,26 @@ class GetModelsTest(TestCase): def test_get_model_only_returns_installed_models(self): self.assertEqual( - app_cache.get_model("not_installed", "NotInstalledModel"), None) + apps.get_model("not_installed", "NotInstalledModel"), None) def test_get_model_with_not_installed(self): self.assertEqual( - app_cache.get_model( + apps.get_model( "not_installed", "NotInstalledModel", only_installed=False), self.not_installed_module.NotInstalledModel) def test_get_models_only_returns_installed_models(self): self.assertNotIn( "NotInstalledModel", - [m.__name__ for m in app_cache.get_models()]) + [m.__name__ for m in apps.get_models()]) def test_get_models_with_app_label_only_returns_installed_models(self): - self.assertEqual(app_cache.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 app_cache.get_models(only_installed=False)]) + [m.__name__ for m in apps.get_models(only_installed=False)]) class NotInstalledModelsTest(TestCase): diff --git a/tests/app_cache/__init__.py b/tests/apps/__init__.py similarity index 100% rename from tests/app_cache/__init__.py rename to tests/apps/__init__.py diff --git a/tests/app_cache/models.py b/tests/apps/models.py similarity index 56% rename from tests/app_cache/models.py rename to tests/apps/models.py index 9306830f9c..c3f764a70b 100644 --- a/tests/app_cache/models.py +++ b/tests/apps/models.py @@ -1,9 +1,9 @@ -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.db import models -# We're testing app cache presence on load, so this is handy. +# We're testing app registry presence on load, so this is handy. -new_app_cache = AppCache() +new_apps = Apps() class TotallyNormal(models.Model): @@ -14,4 +14,4 @@ class SoAlternative(models.Model): name = models.CharField(max_length=255) class Meta: - app_cache = new_app_cache + apps = new_apps diff --git a/tests/apps/tests.py b/tests/apps/tests.py new file mode 100644 index 0000000000..c38d16f8bb --- /dev/null +++ b/tests/apps/tests.py @@ -0,0 +1,51 @@ +from __future__ import absolute_import + +from django.apps import apps +from django.apps.registry import Apps +from django.db import models +from django.test import TestCase + +from .models import TotallyNormal, SoAlternative, new_apps + + +class AppsTests(TestCase): + + def test_models_py(self): + """ + Tests that the models in the models.py file were loaded correctly. + """ + self.assertEqual(apps.get_model("apps", "TotallyNormal"), TotallyNormal) + self.assertEqual(apps.get_model("apps", "SoAlternative"), None) + + self.assertEqual(new_apps.get_model("apps", "TotallyNormal"), None) + self.assertEqual(new_apps.get_model("apps", "SoAlternative"), SoAlternative) + + def test_dynamic_load(self): + """ + Makes a new model at runtime and ensures it goes into the right place. + """ + old_models = apps.get_models(apps.get_app_config("apps").models_module) + # Construct a new model in a new app registry + body = {} + new_apps = Apps() + meta_contents = { + 'app_label': "apps", + 'apps': new_apps, + } + meta = type("Meta", tuple(), meta_contents) + body['Meta'] = meta + body['__module__'] = TotallyNormal.__module__ + temp_model = type("SouthPonies", (models.Model,), body) + # Make sure it appeared in the right place! + self.assertEqual( + old_models, + apps.get_models(apps.get_app_config("apps").models_module), + ) + self.assertEqual(new_apps.get_model("apps", "SouthPonies"), temp_model) + + def test_singleton_master(self): + """ + Ensures that only one master registry can exist. + """ + with self.assertRaises(RuntimeError): + Apps(master=True) diff --git a/tests/base/models.py b/tests/base/models.py index 23efdf9d5b..f84d64df53 100644 --- a/tests/base/models.py +++ b/tests/base/models.py @@ -5,7 +5,7 @@ from django.utils import six # The models definitions below used to crash. Generating models dynamically -# at runtime is a bad idea because it pollutes the app cache. This doesn't +# at runtime is a bad idea because it pollutes the app registry. This doesn't # integrate well with the test suite but at least it prevents regressions. diff --git a/tests/bash_completion/tests.py b/tests/bash_completion/tests.py index 5a6a6c48d2..8653af3c85 100644 --- a/tests/bash_completion/tests.py +++ b/tests/bash_completion/tests.py @@ -5,7 +5,7 @@ import os import sys import unittest -from django.apps import app_cache +from django.apps import apps from django.core.management import ManagementUtility from django.utils.six import StringIO @@ -85,6 +85,6 @@ class BashCompletionTests(unittest.TestCase): self._user_input('django-admin.py sqlall a') output = self._run_autocomplete() a_labels = sorted(app_config.label - for app_config in app_cache.get_app_configs() + for app_config in apps.get_app_configs() if app_config.label.startswith('a')) self.assertEqual(output, a_labels) diff --git a/tests/commands_sql/tests.py b/tests/commands_sql/tests.py index 1c2a7f0ffa..00f4017b9c 100644 --- a/tests/commands_sql/tests.py +++ b/tests/commands_sql/tests.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.core.management.color import no_style from django.core.management.sql import (sql_create, sql_delete, sql_indexes, sql_destroy_indexes, sql_all) @@ -17,7 +17,7 @@ class SQLCommandsTestCase(TestCase): return len([o for o in output if o.startswith(cmd)]) def test_sql_create(self): - app = app_cache.get_app_config('commands_sql').models_module + app = apps.get_app_config('commands_sql').models_module output = sql_create(app, no_style(), connections[DEFAULT_DB_ALIAS]) create_tables = [o for o in output if o.startswith('CREATE TABLE')] self.assertEqual(len(create_tables), 3) @@ -26,7 +26,7 @@ class SQLCommandsTestCase(TestCase): six.assertRegex(self, sql, r'^create table .commands_sql_book.*') def test_sql_delete(self): - app = app_cache.get_app_config('commands_sql').models_module + app = apps.get_app_config('commands_sql').models_module output = sql_delete(app, no_style(), connections[DEFAULT_DB_ALIAS]) drop_tables = [o for o in output if o.startswith('DROP TABLE')] self.assertEqual(len(drop_tables), 3) @@ -35,19 +35,19 @@ class SQLCommandsTestCase(TestCase): six.assertRegex(self, sql, r'^drop table .commands_sql_comment.*') def test_sql_indexes(self): - app = app_cache.get_app_config('commands_sql').models_module + app = apps.get_app_config('commands_sql').models_module output = sql_indexes(app, no_style(), connections[DEFAULT_DB_ALIAS]) # PostgreSQL creates one additional index for CharField self.assertIn(self.count_ddl(output, 'CREATE INDEX'), [3, 4]) def test_sql_destroy_indexes(self): - app = app_cache.get_app_config('commands_sql').models_module + app = apps.get_app_config('commands_sql').models_module output = sql_destroy_indexes(app, no_style(), connections[DEFAULT_DB_ALIAS]) # PostgreSQL creates one additional index for CharField self.assertIn(self.count_ddl(output, 'DROP INDEX'), [3, 4]) def test_sql_all(self): - app = app_cache.get_app_config('commands_sql').models_module + app = apps.get_app_config('commands_sql').models_module output = sql_all(app, no_style(), connections[DEFAULT_DB_ALIAS]) self.assertEqual(self.count_ddl(output, 'CREATE TABLE'), 3) @@ -69,7 +69,7 @@ class SQLCommandsRouterTestCase(TestCase): router.routers = self._old_routers def test_router_honored(self): - app = app_cache.get_app_config('commands_sql').models_module + app = apps.get_app_config('commands_sql').models_module for sql_command in (sql_all, sql_create, sql_delete, sql_indexes, sql_destroy_indexes): output = sql_command(app, no_style(), connections[DEFAULT_DB_ALIAS]) self.assertEqual(len(output), 0, diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index d3c19fd910..1f0af709cb 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.contrib.contenttypes.models import ContentType from django.db import models from django.test import TestCase @@ -61,7 +61,7 @@ class ContentTypesViewsTests(TestCase): class Meta: verbose_name = 'a model created on the fly' app_label = 'my_great_app' - app_cache = AppCache() + apps = Apps() ct = ContentType.objects.get_for_model(ModelCreatedOnTheFly) self.assertEqual(ct.app_label, 'my_great_app') diff --git a/tests/defer_regress/tests.py b/tests/defer_regress/tests.py index b12b3b61b0..22c2d281da 100644 --- a/tests/defer_regress/tests.py +++ b/tests/defer_regress/tests.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from operator import attrgetter -from django.apps import app_cache +from django.apps import apps from django.contrib.contenttypes.models import ContentType from django.contrib.sessions.backends.db import SessionStore from django.db.models import Count @@ -102,7 +102,7 @@ class DeferRegressionTest(TestCase): klasses = set( map( attrgetter("__name__"), - app_cache.get_models(app_cache.get_app_config("defer_regress").models_module) + apps.get_models(apps.get_app_config("defer_regress").models_module) ) ) self.assertIn("Child", klasses) @@ -110,13 +110,13 @@ class DeferRegressionTest(TestCase): self.assertNotIn("Child_Deferred_value", klasses) self.assertNotIn("Item_Deferred_name", klasses) self.assertFalse(any( - k._deferred for k in app_cache.get_models(app_cache.get_app_config("defer_regress").models_module))) + k._deferred for k in apps.get_models(apps.get_app_config("defer_regress").models_module))) klasses_with_deferred = set( map( attrgetter("__name__"), - app_cache.get_models( - app_cache.get_app_config("defer_regress").models_module, include_deferred=True + apps.get_models( + apps.get_app_config("defer_regress").models_module, include_deferred=True ), ) ) @@ -125,8 +125,8 @@ class DeferRegressionTest(TestCase): self.assertIn("Child_Deferred_value", klasses_with_deferred) self.assertIn("Item_Deferred_name", klasses_with_deferred) self.assertTrue(any( - k._deferred for k in app_cache.get_models( - app_cache.get_app_config("defer_regress").models_module, include_deferred=True)) + k._deferred for k in apps.get_models( + apps.get_app_config("defer_regress").models_module, include_deferred=True)) ) @override_settings(SESSION_SERIALIZER='django.contrib.sessions.serializers.PickleSerializer') diff --git a/tests/invalid_models_tests/tests.py b/tests/invalid_models_tests/tests.py index 852e1dbb0d..2c98f39807 100644 --- a/tests/invalid_models_tests/tests.py +++ b/tests/invalid_models_tests/tests.py @@ -1,7 +1,7 @@ import sys import unittest -from django.apps import app_cache +from django.apps import apps from django.core.management.validation import get_validation_errors from django.test import override_settings from django.utils.six import StringIO @@ -32,7 +32,7 @@ class InvalidModelTestCase(unittest.TestCase): TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target', ) def test_invalid_models(self): - module = app_cache.get_app_config("invalid_models").models_module + module = apps.get_app_config("invalid_models").models_module get_validation_errors(self.stdout, module) self.stdout.seek(0) diff --git a/tests/managers_regress/tests.py b/tests/managers_regress/tests.py index bf8e5b17d4..8e0b4cd017 100644 --- a/tests/managers_regress/tests.py +++ b/tests/managers_regress/tests.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.db import models from django.template import Context, Template from django.test import TestCase, override_settings @@ -110,7 +110,7 @@ class ManagersRegressionTests(TestCase): def test_swappable_manager(self): # The models need to be removed after the test in order to prevent bad # interactions with the flush operation in other tests. - _old_models = app_cache.app_configs['managers_regress'].models.copy() + _old_models = apps.app_configs['managers_regress'].models.copy() try: class SwappableModel(models.Model): @@ -126,15 +126,15 @@ class ManagersRegressionTests(TestCase): self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'") finally: - app_cache.app_configs['managers_regress'].models = _old_models - app_cache.all_models['managers_regress'] = _old_models - app_cache.get_models.cache_clear() + apps.app_configs['managers_regress'].models = _old_models + apps.all_models['managers_regress'] = _old_models + apps.get_models.cache_clear() @override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent') def test_custom_swappable_manager(self): # The models need to be removed after the test in order to prevent bad # interactions with the flush operation in other tests. - _old_models = app_cache.app_configs['managers_regress'].models.copy() + _old_models = apps.app_configs['managers_regress'].models.copy() try: class SwappableModel(models.Model): @@ -154,15 +154,15 @@ class ManagersRegressionTests(TestCase): self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'") finally: - app_cache.app_configs['managers_regress'].models = _old_models - app_cache.all_models['managers_regress'] = _old_models - app_cache.get_models.cache_clear() + apps.app_configs['managers_regress'].models = _old_models + apps.all_models['managers_regress'] = _old_models + apps.get_models.cache_clear() @override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent') def test_explicit_swappable_manager(self): # The models need to be removed after the test in order to prevent bad # interactions with the flush operation in other tests. - _old_models = app_cache.app_configs['managers_regress'].models.copy() + _old_models = apps.app_configs['managers_regress'].models.copy() try: class SwappableModel(models.Model): @@ -182,9 +182,9 @@ class ManagersRegressionTests(TestCase): self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'") finally: - app_cache.app_configs['managers_regress'].models = _old_models - app_cache.all_models['managers_regress'] = _old_models - app_cache.get_models.cache_clear() + apps.app_configs['managers_regress'].models = _old_models + apps.all_models['managers_regress'] = _old_models + apps.get_models.cache_clear() def test_regress_3871(self): related = RelatedModel.objects.create() diff --git a/tests/migrations/models.py b/tests/migrations/models.py index b1ef6c1dd1..f76a84054f 100644 --- a/tests/migrations/models.py +++ b/tests/migrations/models.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.db import models from django.utils.encoding import python_2_unicode_compatible @@ -12,7 +12,7 @@ class UnicodeModel(models.Model): class Meta: # Disable auto loading of this model as we load it on our own - app_cache = AppCache() + apps = Apps() verbose_name = 'úñí©óðé µóðéø' verbose_name_plural = 'úñí©óðé µóðéøß' @@ -32,4 +32,4 @@ class UnserializableModel(models.Model): class Meta: # Disable auto loading of this model as we load it on our own - app_cache = AppCache() + apps = Apps() diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index 9fa9be6cbf..3219a62f5a 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -5,7 +5,7 @@ import codecs import os import shutil -from django.apps import app_cache +from django.apps import apps from django.core.management import call_command, CommandError from django.test import override_settings from django.utils import six @@ -131,12 +131,12 @@ class MakeMigrationsTests(MigrationTestBase): self.test_dir = os.path.abspath(os.path.dirname(upath(__file__))) self.migration_dir = os.path.join(self.test_dir, 'migrations_%d' % self.creation_counter) self.migration_pkg = "migrations.migrations_%d" % self.creation_counter - self._old_models = app_cache.app_configs['migrations'].models.copy() + self._old_models = apps.app_configs['migrations'].models.copy() def tearDown(self): - app_cache.app_configs['migrations'].models = self._old_models - app_cache.all_models['migrations'] = self._old_models - app_cache.get_models.cache_clear() + apps.app_configs['migrations'].models = self._old_models + apps.all_models['migrations'] = self._old_models + apps.get_models.cache_clear() os.chdir(self.test_dir) try: @@ -152,7 +152,7 @@ class MakeMigrationsTests(MigrationTestBase): def test_files_content(self): self.assertTableNotExists("migrations_unicodemodel") - app_cache.register_model('migrations', UnicodeModel) + apps.register_model('migrations', UnicodeModel) with override_settings(MIGRATION_MODULES={"migrations": self.migration_pkg}): call_command("makemigrations", "migrations", verbosity=0) @@ -188,7 +188,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_model('migrations', UnserializableModel) + apps.register_model('migrations', UnserializableModel) with six.assertRaisesRegex(self, ValueError, r'Cannot serialize'): with override_settings(MIGRATION_MODULES={"migrations": self.migration_pkg}): diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index 4f0b463f99..7b9ce72aab 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -43,7 +43,7 @@ class LoaderTests(TestCase): def test_load(self): """ Makes sure the loader can load the migrations for the test apps, - and then render them out to a new AppCache. + and then render them out to a new Apps. """ # Load and test the plan migration_loader = MigrationLoader(connection) diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index 0ce030a66c..d11fda23c8 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -203,8 +203,8 @@ class OperationTests(MigrationTestBase): self.assertColumnNotExists("test_adflmm_pony", "stables") # Make sure the M2M field actually works with atomic(): - new_app_cache = new_state.render() - Pony = new_app_cache.get_model("test_adflmm", "Pony") + new_apps = new_state.render() + Pony = new_apps.get_model("test_adflmm", "Pony") p = Pony.objects.create(pink=False, weight=4.55) p.stables.create() self.assertEqual(p.stables.count(), 1) diff --git a/tests/migrations/test_state.py b/tests/migrations/test_state.py index e695248cd2..b7af48fede 100644 --- a/tests/migrations/test_state.py +++ b/tests/migrations/test_state.py @@ -1,4 +1,4 @@ -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.db import models from django.db.migrations.state import ProjectState, ModelState, InvalidBasesError from django.test import TestCase @@ -11,10 +11,10 @@ class StateTests(TestCase): def test_create(self): """ - Tests making a ProjectState from an AppCache + Tests making a ProjectState from an Apps """ - new_app_cache = AppCache() + new_apps = Apps() class Author(models.Model): name = models.CharField(max_length=255) @@ -23,13 +23,13 @@ class StateTests(TestCase): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps unique_together = ["name", "bio"] class AuthorProxy(Author): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps proxy = True ordering = ["name"] @@ -40,11 +40,11 @@ class StateTests(TestCase): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps verbose_name = "tome" db_table = "test_tome" - project_state = ProjectState.from_app_cache(new_app_cache) + project_state = ProjectState.from_apps(new_apps) author_state = project_state.models['migrations', 'author'] author_proxy_state = project_state.models['migrations', 'authorproxy'] book_state = project_state.models['migrations', 'book'] @@ -75,7 +75,7 @@ class StateTests(TestCase): def test_render(self): """ - Tests rendering a ProjectState into an AppCache. + Tests rendering a ProjectState into an Apps. """ project_state = ProjectState() project_state.add_model_state(ModelState( @@ -90,9 +90,9 @@ class StateTests(TestCase): None, )) - new_app_cache = project_state.render() - self.assertEqual(new_app_cache.get_model("migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) - self.assertEqual(new_app_cache.get_model("migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False) + new_apps = project_state.render() + self.assertEqual(new_apps.get_model("migrations", "Tag")._meta.get_field_by_name("name")[0].max_length, 100) + self.assertEqual(new_apps.get_model("migrations", "Tag")._meta.get_field_by_name("hidden")[0].null, False) def test_render_model_inheritance(self): class Book(models.Model): @@ -100,90 +100,90 @@ class StateTests(TestCase): class Meta: app_label = "migrations" - app_cache = AppCache() + apps = Apps() class Novel(Book): class Meta: app_label = "migrations" - app_cache = AppCache() + apps = Apps() # First, test rendering individually - app_cache = AppCache() + apps = Apps() # We shouldn't be able to render yet ms = ModelState.from_model(Novel) with self.assertRaises(InvalidBasesError): - ms.render(app_cache) + ms.render(apps) - # Once the parent model is in the app cache, it should be fine - ModelState.from_model(Book).render(app_cache) - ModelState.from_model(Novel).render(app_cache) + # Once the parent model is in the app registry, it should be fine + ModelState.from_model(Book).render(apps) + ModelState.from_model(Novel).render(apps) def test_render_model_with_multiple_inheritance(self): class Foo(models.Model): class Meta: app_label = "migrations" - app_cache = AppCache() + apps = Apps() class Bar(models.Model): class Meta: app_label = "migrations" - app_cache = AppCache() + apps = Apps() class FooBar(Foo, Bar): class Meta: app_label = "migrations" - app_cache = AppCache() + apps = Apps() - app_cache = AppCache() + apps = Apps() # We shouldn't be able to render yet ms = ModelState.from_model(FooBar) with self.assertRaises(InvalidBasesError): - ms.render(app_cache) + ms.render(apps) - # Once the parent models are in the app cache, it should be fine - ModelState.from_model(Foo).render(app_cache) - ModelState.from_model(Bar).render(app_cache) - ModelState.from_model(FooBar).render(app_cache) + # Once the parent models are in the app registry, it should be fine + ModelState.from_model(Foo).render(apps) + ModelState.from_model(Bar).render(apps) + ModelState.from_model(FooBar).render(apps) def test_render_project_dependencies(self): """ Tests that the ProjectState render method correctly renders models to account for inter-model base dependencies. """ - new_app_cache = AppCache() + new_apps = Apps() class A(models.Model): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps class B(A): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps class C(B): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps class D(A): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps class E(B): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps proxy = True class F(D): class Meta: app_label = "migrations" - app_cache = new_app_cache + apps = new_apps proxy = True # Make a ProjectState and render it @@ -194,8 +194,8 @@ class StateTests(TestCase): project_state.add_model_state(ModelState.from_model(D)) project_state.add_model_state(ModelState.from_model(E)) project_state.add_model_state(ModelState.from_model(F)) - final_app_cache = project_state.render() - self.assertEqual(len(final_app_cache.get_models()), 6) + final_apps = project_state.render() + self.assertEqual(len(final_apps.get_models()), 6) # Now make an invalid ProjectState and make sure it fails project_state = ProjectState() diff --git a/tests/no_models/tests.py b/tests/no_models/tests.py index f9ff80485e..bd17364071 100644 --- a/tests/no_models/tests.py +++ b/tests/no_models/tests.py @@ -1,4 +1,4 @@ -from django.apps import app_cache +from django.apps import apps from django.test import TestCase @@ -6,5 +6,5 @@ class NoModelTests(TestCase): def test_no_models(self): """Test that it's possible to load an app with no models.py file.""" - app_config = app_cache.get_app_config('no_models') + app_config = apps.get_app_config('no_models') self.assertIsNone(app_config.models_module) diff --git a/tests/proxy_models/tests.py b/tests/proxy_models/tests.py index 4a3d6e5e5a..fe294aeb1e 100644 --- a/tests/proxy_models/tests.py +++ b/tests/proxy_models/tests.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.contrib import admin from django.contrib.contenttypes.models import ContentType from django.core import management @@ -155,7 +155,7 @@ class ProxyModelTests(TestCase): def test_swappable(self): # The models need to be removed after the test in order to prevent bad # interactions with the flush operation in other tests. - _old_models = app_cache.app_configs['proxy_models'].models.copy() + _old_models = apps.app_configs['proxy_models'].models.copy() try: class SwappableModel(models.Model): @@ -173,9 +173,9 @@ class ProxyModelTests(TestCase): class Meta: proxy = True finally: - app_cache.app_configs['proxy_models'].models = _old_models - app_cache.all_models['proxy_models'] = _old_models - app_cache.get_models.cache_clear() + apps.app_configs['proxy_models'].models = _old_models + apps.all_models['proxy_models'] = _old_models + apps.get_models.cache_clear() def test_myperson_manager(self): Person.objects.create(name="fred") diff --git a/tests/runtests.py b/tests/runtests.py index ab6f778a81..5f39eef400 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -80,13 +80,13 @@ def get_test_modules(): def get_installed(): - from django.apps import app_cache - return [app_config.name for app_config in app_cache.get_app_configs()] + from django.apps import apps + return [app_config.name for app_config in apps.get_app_configs()] def setup(verbosity, test_labels): import django - from django.apps import app_cache, AppConfig + from django.apps import apps, AppConfig from django.conf import settings from django.test import TransactionTestCase, TestCase @@ -128,7 +128,7 @@ def setup(verbosity, test_labels): # Load all the ALWAYS_INSTALLED_APPS. with warnings.catch_warnings(): warnings.filterwarnings('ignore', 'django.contrib.comments is deprecated and will be removed before Django 1.8.', DeprecationWarning) - app_cache.populate_models() + apps.populate_models() # Load all the test model apps. test_modules = get_test_modules() @@ -168,9 +168,9 @@ def setup(verbosity, test_labels): if module_label not in settings.INSTALLED_APPS: settings.INSTALLED_APPS.append(module_label) app_config = AppConfig.create(module_label) - app_config.import_models(app_cache.all_models[app_config.label]) - app_cache.app_configs[app_config.label] = app_config - app_cache.get_models.cache_clear() + app_config.import_models(apps.all_models[app_config.label]) + apps.app_configs[app_config.label] = app_config + apps.get_models.cache_clear() return state diff --git a/tests/schema/models.py b/tests/schema/models.py index b294647f9b..44fecf7ebd 100644 --- a/tests/schema/models.py +++ b/tests/schema/models.py @@ -1,11 +1,11 @@ -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.db import models # Because we want to test creation and deletion of these as separate things, -# these models are all inserted into a separate AppCache so the main test +# these models are all inserted into a separate Apps so the main test # runner doesn't migrate them. -new_app_cache = AppCache() +new_apps = Apps() class Author(models.Model): @@ -13,14 +13,14 @@ class Author(models.Model): height = models.PositiveIntegerField(null=True, blank=True) class Meta: - app_cache = new_app_cache + apps = new_apps class AuthorWithM2M(models.Model): name = models.CharField(max_length=255) class Meta: - app_cache = new_app_cache + apps = new_apps class Book(models.Model): @@ -30,7 +30,7 @@ class Book(models.Model): # tags = models.ManyToManyField("Tag", related_name="books") class Meta: - app_cache = new_app_cache + apps = new_apps class BookWithM2M(models.Model): @@ -40,7 +40,7 @@ class BookWithM2M(models.Model): tags = models.ManyToManyField("TagM2MTest", related_name="books") class Meta: - app_cache = new_app_cache + apps = new_apps class BookWithSlug(models.Model): @@ -50,7 +50,7 @@ class BookWithSlug(models.Model): slug = models.CharField(max_length=20, unique=True) class Meta: - app_cache = new_app_cache + apps = new_apps db_table = "schema_book" @@ -59,7 +59,7 @@ class Tag(models.Model): slug = models.SlugField(unique=True) class Meta: - app_cache = new_app_cache + apps = new_apps class TagM2MTest(models.Model): @@ -67,7 +67,7 @@ class TagM2MTest(models.Model): slug = models.SlugField(unique=True) class Meta: - app_cache = new_app_cache + apps = new_apps class TagIndexed(models.Model): @@ -75,7 +75,7 @@ class TagIndexed(models.Model): slug = models.SlugField(unique=True) class Meta: - app_cache = new_app_cache + apps = new_apps index_together = [["slug", "title"]] @@ -84,7 +84,7 @@ class TagUniqueRename(models.Model): slug2 = models.SlugField(unique=True) class Meta: - app_cache = new_app_cache + apps = new_apps db_table = "schema_tag" @@ -93,7 +93,7 @@ class UniqueTest(models.Model): slug = models.SlugField(unique=False) class Meta: - app_cache = new_app_cache + apps = new_apps unique_together = ["year", "slug"] @@ -101,4 +101,4 @@ class BookWithLongName(models.Model): author_foreign_key_with_really_long_field_name = models.ForeignKey(Author) class Meta: - app_cache = new_app_cache + apps = new_apps diff --git a/tests/swappable_models/tests.py b/tests/swappable_models/tests.py index c703a99fcb..3bf5b46d66 100644 --- a/tests/swappable_models/tests.py +++ b/tests/swappable_models/tests.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.utils.six import StringIO -from django.apps import app_cache +from django.apps import apps from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.core import management diff --git a/tests/tablespaces/tests.py b/tests/tablespaces/tests.py index fdee877a9f..5e22608551 100644 --- a/tests/tablespaces/tests.py +++ b/tests/tablespaces/tests.py @@ -1,6 +1,6 @@ from __future__ import unicode_literals -from django.apps import app_cache +from django.apps import apps from django.conf import settings from django.db import connection from django.core.management.color import no_style @@ -26,7 +26,7 @@ class TablespacesTests(TestCase): def setUp(self): # The unmanaged models need to be removed after the test in order to # prevent bad interactions with the flush operation in other tests. - self._old_models = app_cache.app_configs['tablespaces'].models.copy() + self._old_models = apps.app_configs['tablespaces'].models.copy() for model in Article, Authors, Reviewers, Scientist: model._meta.managed = True @@ -35,9 +35,9 @@ class TablespacesTests(TestCase): for model in Article, Authors, Reviewers, Scientist: model._meta.managed = False - app_cache.app_configs['tablespaces'].models = self._old_models - app_cache.all_models['tablespaces'] = self._old_models - app_cache.get_models.cache_clear() + apps.app_configs['tablespaces'].models = self._old_models + apps.all_models['tablespaces'] = self._old_models + apps.get_models.cache_clear() def assertNumContains(self, haystack, needle, count): real_count = haystack.count(needle) diff --git a/tests/test_suite_override/tests.py b/tests/test_suite_override/tests.py index 9666df1c19..c485b801bc 100644 --- a/tests/test_suite_override/tests.py +++ b/tests/test_suite_override/tests.py @@ -1,6 +1,6 @@ import unittest -from django.apps import app_cache +from django.apps import apps from django.test.utils import IgnoreAllDeprecationWarningsMixin @@ -20,7 +20,7 @@ class SuiteOverrideTest(IgnoreAllDeprecationWarningsMixin, unittest.TestCase): """ from django.test.simple import build_suite - app_config = app_cache.get_app_config("test_suite_override") + app_config = apps.get_app_config("test_suite_override") suite = build_suite(app_config) self.assertEqual(suite.countTestCases(), 1) diff --git a/tests/validation/test_unique.py b/tests/validation/test_unique.py index be7808f460..76c7ec174f 100644 --- a/tests/validation/test_unique.py +++ b/tests/validation/test_unique.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import datetime import unittest -from django.apps.cache import AppCache +from django.apps.registry import Apps from django.core.exceptions import ValidationError from django.db import models from django.test import TestCase @@ -58,7 +58,7 @@ class GetUniqueCheckTests(unittest.TestCase): Meta = type(str('Meta'), (), { 'unique_together': unique_together, - 'app_cache': AppCache() + 'apps': Apps() }) checks, _ = M()._get_unique_checks()