Skip to content

Commit d7f9554

Browse files
sarahboycenessita
authored andcommitted
[5.0.x] Fixed #35657 -- Made FileField handle db_default values.
Backport of 8deb6bb from main.
1 parent 333cfab commit d7f9554

File tree

4 files changed

+27
-0
lines changed

4 files changed

+27
-0
lines changed

django/db/models/fields/files.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from django.core.files.storage import Storage, default_storage
99
from django.core.files.utils import validate_file_name
1010
from django.db.models import signals
11+
from django.db.models.expressions import DatabaseDefault
1112
from django.db.models.fields import Field
1213
from django.db.models.query_utils import DeferredAttribute
1314
from django.db.models.utils import AltersData
@@ -192,6 +193,12 @@ def __get__(self, instance, cls=None):
192193
attr = self.field.attr_class(instance, self.field, file)
193194
instance.__dict__[self.field.attname] = attr
194195

196+
# If this value is a DatabaseDefault, initialize the attribute class
197+
# for this field with its db_default value.
198+
elif isinstance(file, DatabaseDefault):
199+
attr = self.field.attr_class(instance, self.field, self.field.db_default)
200+
instance.__dict__[self.field.attname] = attr
201+
195202
# Other types of files may be assigned as well, but they need to have
196203
# the FieldFile interface added to them. Thus, we wrap any other type of
197204
# File inside a FieldFile (well, the field's attr_class, which is

docs/releases/5.0.8.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ Bugfixes
3232
* Fixed a bug in Django 5.0 which caused constraint validation to either crash
3333
or incorrectly raise validation errors for constraints referring to fields
3434
using ``Field.db_default`` (:ticket:`35638`).
35+
36+
* Fixed a crash in Django 5.0 when saving a model containing a ``FileField``
37+
with a ``db_default`` set (:ticket:`35657`).

tests/file_storage/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ def pathlib_upload_to(self, filename):
7272
default = models.FileField(
7373
storage=temp_storage, upload_to="tests", default="tests/default.txt"
7474
)
75+
db_default = models.FileField(
76+
storage=temp_storage, upload_to="tests", db_default="tests/db_default.txt"
77+
)
7578
empty = models.FileField(storage=temp_storage)
7679
limited_length = models.FileField(
7780
storage=temp_storage, upload_to="tests", max_length=20

tests/file_storage/tests.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,20 @@ def test_filefield_default(self):
895895
self.assertEqual(obj.default.read(), b"default content")
896896
obj.default.close()
897897

898+
def test_filefield_db_default(self):
899+
temp_storage.save("tests/db_default.txt", ContentFile("default content"))
900+
obj = Storage.objects.create()
901+
self.assertEqual(obj.db_default.name, "tests/db_default.txt")
902+
self.assertEqual(obj.db_default.read(), b"default content")
903+
obj.db_default.close()
904+
905+
# File is not deleted, even if there are no more objects using it.
906+
obj.delete()
907+
s = Storage()
908+
self.assertEqual(s.db_default.name, "tests/db_default.txt")
909+
self.assertEqual(s.db_default.read(), b"default content")
910+
s.db_default.close()
911+
898912
def test_empty_upload_to(self):
899913
# upload_to can be empty, meaning it does not use subdirectory.
900914
obj = Storage()

0 commit comments

Comments
 (0)