diff --git a/django/conf/__init__.py b/django/conf/__init__.py index da461ecc026..e03369d3217 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -222,6 +222,9 @@ class Settings: raise ImproperlyConfigured( "DEFAULT_FILE_STORAGE/STORAGES are mutually exclusive." ) + self.STORAGES[DEFAULT_STORAGE_ALIAS] = { + "BACKEND": self.DEFAULT_FILE_STORAGE + } warnings.warn(DEFAULT_FILE_STORAGE_DEPRECATED_MSG, RemovedInDjango51Warning) if self.is_overridden("STATICFILES_STORAGE"): @@ -229,7 +232,22 @@ class Settings: raise ImproperlyConfigured( "STATICFILES_STORAGE/STORAGES are mutually exclusive." ) + self.STORAGES[STATICFILES_STORAGE_ALIAS] = { + "BACKEND": self.STATICFILES_STORAGE + } warnings.warn(STATICFILES_STORAGE_DEPRECATED_MSG, RemovedInDjango51Warning) + # RemovedInDjango51Warning. + if self.is_overridden("STORAGES"): + setattr( + self, + "DEFAULT_FILE_STORAGE", + self.STORAGES.get(DEFAULT_STORAGE_ALIAS, {}).get("BACKEND"), + ) + setattr( + self, + "STATICFILES_STORAGE", + self.STORAGES.get(STATICFILES_STORAGE_ALIAS, {}).get("BACKEND"), + ) def is_overridden(self, setting): return setting in self._explicit_settings @@ -276,14 +294,28 @@ class UserSettingsHolder: super().__setattr__(name, value) # RemovedInDjango51Warning. if name == "STORAGES": - self.STORAGES.setdefault( - DEFAULT_STORAGE_ALIAS, - {"BACKEND": "django.core.files.storage.FileSystemStorage"}, - ) - self.STORAGES.setdefault( - STATICFILES_STORAGE_ALIAS, - {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"}, - ) + if default_file_storage := self.STORAGES.get(DEFAULT_STORAGE_ALIAS): + super().__setattr__( + "DEFAULT_FILE_STORAGE", default_file_storage.get("BACKEND") + ) + else: + self.STORAGES.setdefault( + DEFAULT_STORAGE_ALIAS, + {"BACKEND": "django.core.files.storage.FileSystemStorage"}, + ) + if staticfiles_storage := self.STORAGES.get(STATICFILES_STORAGE_ALIAS): + super().__setattr__( + "STATICFILES_STORAGE", staticfiles_storage.get("BACKEND") + ) + else: + self.STORAGES.setdefault( + STATICFILES_STORAGE_ALIAS, + { + "BACKEND": ( + "django.contrib.staticfiles.storage.StaticFilesStorage" + ), + }, + ) def __delattr__(self, name): self._deleted.add(name) diff --git a/docs/releases/4.2.5.txt b/docs/releases/4.2.5.txt index 23ba728da56..480b21d9028 100644 --- a/docs/releases/4.2.5.txt +++ b/docs/releases/4.2.5.txt @@ -12,3 +12,7 @@ Bugfixes * Fixed a regression in Django 4.2 that caused an incorrect validation of ``CheckConstraints`` on ``__isnull`` lookups against ``JSONField`` (:ticket:`34754`). + +* Fixed a bug in Django 4.2 where the deprecated ``DEFAULT_FILE_STORAGE`` and + ``STATICFILES_STORAGE`` settings were not synced with ``STORAGES`` + (:ticket:`34773`). diff --git a/tests/deprecation/test_storages.py b/tests/deprecation/test_storages.py index 71ed3acdb03..0574f3e880f 100644 --- a/tests/deprecation/test_storages.py +++ b/tests/deprecation/test_storages.py @@ -39,8 +39,36 @@ class StaticfilesStorageDeprecationTests(TestCase): ) sys.modules["fake_settings_module"] = settings_module try: - with self.assertRaisesMessage(RemovedInDjango51Warning, self.msg): - Settings("fake_settings_module") + with self.assertWarnsMessage(RemovedInDjango51Warning, self.msg): + fake_settings = Settings("fake_settings_module") + self.assertEqual( + fake_settings.STORAGES[STATICFILES_STORAGE_ALIAS], + { + "BACKEND": ( + "django.contrib.staticfiles.storage.ManifestStaticFilesStorage" + ), + }, + ) + finally: + del sys.modules["fake_settings_module"] + + def test_settings_storages_init(self): + settings_module = ModuleType("fake_settings_module") + settings_module.USE_TZ = True + settings_module.STORAGES = { + STATICFILES_STORAGE_ALIAS: { + "BACKEND": ( + "django.contrib.staticfiles.storage.ManifestStaticFilesStorage" + ) + } + } + sys.modules["fake_settings_module"] = settings_module + try: + fake_settings = Settings("fake_settings_module") + self.assertEqual( + fake_settings.STATICFILES_STORAGE, + "django.contrib.staticfiles.storage.ManifestStaticFilesStorage", + ) finally: del sys.modules["fake_settings_module"] @@ -101,6 +129,26 @@ class StaticfilesStorageDeprecationTests(TestCase): ) self.assertIsInstance(staticfiles_storage, ManifestStaticFilesStorage) + @ignore_warnings(category=RemovedInDjango51Warning) + def test_staticfiles_storage(self): + with self.settings( + STORAGES={ + STATICFILES_STORAGE_ALIAS: { + "BACKEND": ( + "django.contrib.staticfiles.storage.ManifestStaticFilesStorage" + ) + } + } + ): + self.assertEqual( + settings.STATICFILES_STORAGE, + "django.contrib.staticfiles.storage.ManifestStaticFilesStorage", + ) + self.assertIsInstance( + storages[STATICFILES_STORAGE_ALIAS], + ManifestStaticFilesStorage, + ) + class DefaultStorageDeprecationTests(TestCase): msg = DEFAULT_FILE_STORAGE_DEPRECATED_MSG @@ -118,8 +166,30 @@ class DefaultStorageDeprecationTests(TestCase): settings_module.DEFAULT_FILE_STORAGE = "django.core.files.storage.Storage" sys.modules["fake_settings_module"] = settings_module try: - with self.assertRaisesMessage(RemovedInDjango51Warning, self.msg): - Settings("fake_settings_module") + with self.assertWarnsMessage(RemovedInDjango51Warning, self.msg): + fake_settings = Settings("fake_settings_module") + self.assertEqual( + fake_settings.STORAGES[DEFAULT_STORAGE_ALIAS], + {"BACKEND": "django.core.files.storage.Storage"}, + ) + finally: + del sys.modules["fake_settings_module"] + + def test_settings_storages_init(self): + settings_module = ModuleType("fake_settings_module") + settings_module.USE_TZ = True + settings_module.STORAGES = { + DEFAULT_STORAGE_ALIAS: { + "BACKEND": "django.core.files.storage.Storage", + } + } + sys.modules["fake_settings_module"] = settings_module + try: + fake_settings = Settings("fake_settings_module") + self.assertEqual( + fake_settings.DEFAULT_FILE_STORAGE, + "django.core.files.storage.Storage", + ) finally: del sys.modules["fake_settings_module"] @@ -163,3 +233,18 @@ class DefaultStorageDeprecationTests(TestCase): self.assertIsInstance(storages[DEFAULT_STORAGE_ALIAS], Storage) self.assertIsInstance(empty_storages[DEFAULT_STORAGE_ALIAS], Storage) self.assertIsInstance(default_storage, Storage) + + @ignore_warnings(category=RemovedInDjango51Warning) + def test_default_file_storage(self): + with self.settings( + STORAGES={ + DEFAULT_STORAGE_ALIAS: { + "BACKEND": "django.core.files.storage.Storage", + } + } + ): + self.assertEqual( + settings.DEFAULT_FILE_STORAGE, + "django.core.files.storage.Storage", + ) + self.assertIsInstance(storages[DEFAULT_STORAGE_ALIAS], Storage)