From 5c114ce2d8479549ee9dd486bc28df5b2e3d54ad Mon Sep 17 00:00:00 2001 From: Clifford Gama Date: Thu, 9 Oct 2025 21:24:06 +0200 Subject: [PATCH] [6.0.x] Fixed 36622 -- Prevented LazyObject FileField storages from evaluating at boot time. Co-authored-by: Fabien MICHEL Backport of 6862d46dd96d71d80d6d2fa9873a93d811b39562 from main. --- django/db/models/fields/files.py | 2 +- tests/file_storage/models.py | 7 +++++++ tests/file_storage/tests.py | 9 +++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 5216ff565f..dbf227ae92 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -248,7 +248,7 @@ class FileField(Field): ): self._primary_key_set_explicitly = "primary_key" in kwargs - self.storage = storage or default_storage + self.storage = storage if storage is not None else default_storage if callable(self.storage): # Hold a reference to the callable for deconstruct(). self._storage_callable = self.storage diff --git a/tests/file_storage/models.py b/tests/file_storage/models.py index 12a54edda5..d1761c8510 100644 --- a/tests/file_storage/models.py +++ b/tests/file_storage/models.py @@ -11,6 +11,7 @@ from pathlib import Path from django.core.files.storage import FileSystemStorage, default_storage from django.db import models +from django.utils.functional import LazyObject class CustomValidNameStorage(FileSystemStorage): @@ -37,6 +38,11 @@ class CallableStorage(FileSystemStorage): return self +class LazyTempStorage(LazyObject): + def _setup(self): + self._wrapped = temp_storage + + class Storage(models.Model): def custom_upload_to(self, filename): return "foo" @@ -82,3 +88,4 @@ class Storage(models.Model): extended_length = models.FileField( storage=temp_storage, upload_to="tests", max_length=1024 ) + lazy_storage = models.FileField(storage=LazyTempStorage(), upload_to="tests") diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index a0234b2f9d..92962bd9a0 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -29,6 +29,7 @@ from django.test.utils import requires_tz_support from django.urls import NoReverseMatch, reverse_lazy from django.utils import timezone from django.utils._os import symlinks_supported +from django.utils.functional import empty from .models import ( Storage, @@ -1267,3 +1268,11 @@ class StorageHandlerTests(SimpleTestCase): ) with self.assertRaisesMessage(InvalidStorageError, msg): test_storages["invalid_backend"] + + +class StorageLazyObjectTests(SimpleTestCase): + def test_lazy_object_is_not_evaluated_before_manual_access(self): + obj = Storage() + self.assertIs(obj.lazy_storage.storage._wrapped, empty) + # assertEqual triggers resolution. + self.assertEqual(obj.lazy_storage.storage, temp_storage)