Fixed #21238 -- Fixed restoring attributes when pickling FileField and ImageField.

This commit is contained in:
Hasan Ramezani 2019-11-10 22:55:48 +01:00 committed by Mariusz Felisiak
parent aaea9deac4
commit f600e3fad6
3 changed files with 23 additions and 5 deletions

View File

@ -123,11 +123,21 @@ class FieldFile(File):
file.close() file.close()
def __getstate__(self): def __getstate__(self):
# FieldFile needs access to its associated model field and an instance # FieldFile needs access to its associated model field, an instance and
# it's attached to in order to work properly, but the only necessary # the file's name. Everything else will be restored later, by
# data to be pickled is the file's name itself. Everything else will # FileDescriptor below.
# be restored later, by FileDescriptor below. return {
return {'name': self.name, 'closed': False, '_committed': True, '_file': None} 'name': self.name,
'closed': False,
'_committed': True,
'_file': None,
'instance': self.instance,
'field': self.field,
}
def __setstate__(self, state):
self.__dict__.update(state)
self.storage = self.field.storage
class FileDescriptor: class FileDescriptor:

View File

@ -122,3 +122,7 @@ class FileFieldTests(TestCase):
myfile_dump = pickle.dumps(document.myfile) myfile_dump = pickle.dumps(document.myfile)
loaded_myfile = pickle.loads(myfile_dump) loaded_myfile = pickle.loads(myfile_dump)
self.assertEqual(document.myfile, loaded_myfile) self.assertEqual(document.myfile, loaded_myfile)
self.assertEqual(document.myfile.url, loaded_myfile.url)
self.assertEqual(document.myfile.storage, loaded_myfile.storage)
self.assertEqual(document.myfile.instance, loaded_myfile.instance)
self.assertEqual(document.myfile.field, loaded_myfile.field)

View File

@ -188,6 +188,10 @@ class ImageFieldTests(ImageFieldTestMixin, TestCase):
mugshot_dump = pickle.dumps(p.mugshot) mugshot_dump = pickle.dumps(p.mugshot)
loaded_mugshot = pickle.loads(mugshot_dump) loaded_mugshot = pickle.loads(mugshot_dump)
self.assertEqual(p.mugshot, loaded_mugshot) self.assertEqual(p.mugshot, loaded_mugshot)
self.assertEqual(p.mugshot.url, loaded_mugshot.url)
self.assertEqual(p.mugshot.storage, loaded_mugshot.storage)
self.assertEqual(p.mugshot.instance, loaded_mugshot.instance)
self.assertEqual(p.mugshot.field, loaded_mugshot.field)
def test_defer(self): def test_defer(self):
self.PersonModel.objects.create(name='Joe', mugshot=self.file1) self.PersonModel.objects.create(name='Joe', mugshot=self.file1)