mirror of https://github.com/django/django.git
Fixed #35657 -- Made FileField handle db_default values.
This commit is contained in:
parent
e9e14709ff
commit
8deb6bb1fc
|
@ -9,6 +9,7 @@ from django.core.files.images import ImageFile
|
||||||
from django.core.files.storage import Storage, default_storage
|
from django.core.files.storage import Storage, default_storage
|
||||||
from django.core.files.utils import validate_file_name
|
from django.core.files.utils import validate_file_name
|
||||||
from django.db.models import signals
|
from django.db.models import signals
|
||||||
|
from django.db.models.expressions import DatabaseDefault
|
||||||
from django.db.models.fields import Field
|
from django.db.models.fields import Field
|
||||||
from django.db.models.query_utils import DeferredAttribute
|
from django.db.models.query_utils import DeferredAttribute
|
||||||
from django.db.models.utils import AltersData
|
from django.db.models.utils import AltersData
|
||||||
|
@ -197,6 +198,12 @@ class FileDescriptor(DeferredAttribute):
|
||||||
attr = self.field.attr_class(instance, self.field, file)
|
attr = self.field.attr_class(instance, self.field, file)
|
||||||
instance.__dict__[self.field.attname] = attr
|
instance.__dict__[self.field.attname] = attr
|
||||||
|
|
||||||
|
# If this value is a DatabaseDefault, initialize the attribute class
|
||||||
|
# for this field with its db_default value.
|
||||||
|
elif isinstance(file, DatabaseDefault):
|
||||||
|
attr = self.field.attr_class(instance, self.field, self.field.db_default)
|
||||||
|
instance.__dict__[self.field.attname] = attr
|
||||||
|
|
||||||
# Other types of files may be assigned as well, but they need to have
|
# Other types of files may be assigned as well, but they need to have
|
||||||
# the FieldFile interface added to them. Thus, we wrap any other type of
|
# the FieldFile interface added to them. Thus, we wrap any other type of
|
||||||
# File inside a FieldFile (well, the field's attr_class, which is
|
# File inside a FieldFile (well, the field's attr_class, which is
|
||||||
|
|
|
@ -32,3 +32,6 @@ Bugfixes
|
||||||
* Fixed a bug in Django 5.0 which caused constraint validation to either crash
|
* Fixed a bug in Django 5.0 which caused constraint validation to either crash
|
||||||
or incorrectly raise validation errors for constraints referring to fields
|
or incorrectly raise validation errors for constraints referring to fields
|
||||||
using ``Field.db_default`` (:ticket:`35638`).
|
using ``Field.db_default`` (:ticket:`35638`).
|
||||||
|
|
||||||
|
* Fixed a crash in Django 5.0 when saving a model containing a ``FileField``
|
||||||
|
with a ``db_default`` set (:ticket:`35657`).
|
||||||
|
|
|
@ -72,6 +72,9 @@ class Storage(models.Model):
|
||||||
default = models.FileField(
|
default = models.FileField(
|
||||||
storage=temp_storage, upload_to="tests", default="tests/default.txt"
|
storage=temp_storage, upload_to="tests", default="tests/default.txt"
|
||||||
)
|
)
|
||||||
|
db_default = models.FileField(
|
||||||
|
storage=temp_storage, upload_to="tests", db_default="tests/db_default.txt"
|
||||||
|
)
|
||||||
empty = models.FileField(storage=temp_storage)
|
empty = models.FileField(storage=temp_storage)
|
||||||
limited_length = models.FileField(
|
limited_length = models.FileField(
|
||||||
storage=temp_storage, upload_to="tests", max_length=20
|
storage=temp_storage, upload_to="tests", max_length=20
|
||||||
|
|
|
@ -944,6 +944,20 @@ class FileFieldStorageTests(TestCase):
|
||||||
self.assertEqual(obj.default.read(), b"default content")
|
self.assertEqual(obj.default.read(), b"default content")
|
||||||
obj.default.close()
|
obj.default.close()
|
||||||
|
|
||||||
|
def test_filefield_db_default(self):
|
||||||
|
temp_storage.save("tests/db_default.txt", ContentFile("default content"))
|
||||||
|
obj = Storage.objects.create()
|
||||||
|
self.assertEqual(obj.db_default.name, "tests/db_default.txt")
|
||||||
|
self.assertEqual(obj.db_default.read(), b"default content")
|
||||||
|
obj.db_default.close()
|
||||||
|
|
||||||
|
# File is not deleted, even if there are no more objects using it.
|
||||||
|
obj.delete()
|
||||||
|
s = Storage()
|
||||||
|
self.assertEqual(s.db_default.name, "tests/db_default.txt")
|
||||||
|
self.assertEqual(s.db_default.read(), b"default content")
|
||||||
|
s.db_default.close()
|
||||||
|
|
||||||
def test_empty_upload_to(self):
|
def test_empty_upload_to(self):
|
||||||
# upload_to can be empty, meaning it does not use subdirectory.
|
# upload_to can be empty, meaning it does not use subdirectory.
|
||||||
obj = Storage()
|
obj = Storage()
|
||||||
|
|
Loading…
Reference in New Issue