summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2016-07-15 15:54:11 -0400
committerTim Graham <timograham@gmail.com>2016-07-16 08:22:24 -0400
commit7c33aa8a87d323f0e8e5368705aa8ba96f9819d0 (patch)
tree209b3f70add084d1c0e82f61d25a10f3141fc35c
parent255fb992845e987ef36e3d721a77747a0b2df620 (diff)
Fixed #26900 -- Fixed crash accessing deferred FileFields.
-rw-r--r--django/db/models/fields/files.py11
-rw-r--r--tests/model_fields/test_filefield.py4
-rw-r--r--tests/model_fields/test_imagefield.py7
3 files changed, 19 insertions, 3 deletions
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index 8dfd9bf08d..659bb4c518 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -168,7 +168,11 @@ class FileDescriptor(object):
# The instance dict contains whatever was originally assigned
# in __set__.
- file = instance.__dict__[self.field.name]
+ if self.field.name in instance.__dict__:
+ file = instance.__dict__[self.field.name]
+ else:
+ instance.refresh_from_db(fields=[self.field.name])
+ file = getattr(instance, self.field.name)
# If this value is a string (instance.file = "path/to/file") or None
# then we simply wrap it with the appropriate attribute class according
@@ -439,9 +443,10 @@ class ImageField(FileField):
Dimensions can be forced to update with force=True, which is how
ImageFileDescriptor.__set__ calls this method.
"""
- # Nothing to update if the field doesn't have dimension fields.
+ # Nothing to update if the field doesn't have dimension fields or if
+ # the field is deferred.
has_dimension_fields = self.width_field or self.height_field
- if not has_dimension_fields:
+ if not has_dimension_fields or self.attname not in instance.__dict__:
return
# getattr will call the ImageFileDescriptor's __get__ method, which
diff --git a/tests/model_fields/test_filefield.py b/tests/model_fields/test_filefield.py
index 3b0ef5726d..19d414161d 100644
--- a/tests/model_fields/test_filefield.py
+++ b/tests/model_fields/test_filefield.py
@@ -50,3 +50,7 @@ class FileFieldTests(TestCase):
d = Document.objects.create(myfile='something.txt')
d.refresh_from_db()
self.assertIs(d.myfile.instance, d)
+
+ def test_defer(self):
+ Document.objects.create(myfile='something.txt')
+ self.assertEqual(Document.objects.defer('myfile')[0].myfile, 'something.txt')
diff --git a/tests/model_fields/test_imagefield.py b/tests/model_fields/test_imagefield.py
index 51f91d90c0..a70394795f 100644
--- a/tests/model_fields/test_imagefield.py
+++ b/tests/model_fields/test_imagefield.py
@@ -194,6 +194,13 @@ class ImageFieldTests(ImageFieldTestMixin, TestCase):
loaded_p = pickle.loads(dump)
self.assertEqual(p.mugshot, loaded_p.mugshot)
+ def test_defer(self):
+ self.PersonModel.objects.create(name='Joe', mugshot=self.file1)
+ with self.assertNumQueries(1):
+ qs = list(self.PersonModel.objects.defer('mugshot'))
+ with self.assertNumQueries(0):
+ self.assertEqual(qs[0].name, 'Joe')
+
@skipIf(Image is None, "Pillow is required to test ImageField")
class ImageFieldTwoDimensionsTests(ImageFieldTestMixin, TestCase):