diff options
| author | Tim Graham <timograham@gmail.com> | 2016-07-15 15:54:11 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-07-16 08:47:29 -0400 |
| commit | a03ac61332fe356a60e25d5ecd7d4cd7ee07c345 (patch) | |
| tree | e96a7daf3a05675d9d9b8d0623beed9a668644d3 | |
| parent | 6646a396cc20c550508599c987d25036a2354bd9 (diff) | |
[1.10.x] Fixed #26900 -- Fixed crash accessing deferred FileFields.
Backport of 7c33aa8a87d323f0e8e5368705aa8ba96f9819d0 from master
| -rw-r--r-- | django/db/models/fields/files.py | 11 | ||||
| -rw-r--r-- | tests/model_fields/test_filefield.py | 4 | ||||
| -rw-r--r-- | tests/model_fields/test_imagefield.py | 7 |
3 files changed, 19 insertions, 3 deletions
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index e3a3fee8f6..3c75c8a1e0 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -167,7 +167,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 @@ -437,9 +441,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 f9ae83b8b2..f4e8f515a2 100644 --- a/tests/model_fields/test_imagefield.py +++ b/tests/model_fields/test_imagefield.py @@ -188,6 +188,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): |
