0
0
mirror of https://github.com/django/django.git synced 2024-11-29 22:56:46 +01:00

Fixed #6456 - Excised FileField file deletion to avoid data loss. Thanks to durdinator for the report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15321 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Carl Meyer 2011-01-26 07:46:19 +00:00
parent 80287f1e8a
commit 00e7a571c5
3 changed files with 16 additions and 16 deletions

View File

@ -258,19 +258,6 @@ class FileField(Field):
def contribute_to_class(self, cls, name): def contribute_to_class(self, cls, name):
super(FileField, self).contribute_to_class(cls, name) super(FileField, self).contribute_to_class(cls, name)
setattr(cls, self.name, self.descriptor_class(self)) setattr(cls, self.name, self.descriptor_class(self))
signals.post_delete.connect(self.delete_file, sender=cls)
def delete_file(self, instance, sender, **kwargs):
file = getattr(instance, self.attname)
# If no other object of this type references the file,
# and it's not the default value for future objects,
# delete it from the backend.
if file and file.name != self.default and \
not sender._default_manager.filter(**{self.name: file.name}):
file.delete(save=False)
elif file:
# Otherwise, just close the file, so it doesn't tie up resources.
file.close()
def get_directory_name(self): def get_directory_name(self):
return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to)))) return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to))))

View File

@ -261,6 +261,20 @@ requests. These include:
Backwards-incompatible changes in 1.3 Backwards-incompatible changes in 1.3
===================================== =====================================
FileField no longer deletes files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In earlier Django versions, when a model instance containing a
:class:`~django.db.models.FileField` was deleted,
:class:`~django.db.models.FileField` took it upon itself to also delete the
file from the backend storage. This opened the door to several data-loss
scenarios, including rolled-back transactions and fields on different models
referencing the same file. In Django 1.3, :class:`~django.db.models.FileField`
will never delete files from the backend storage. If you need cleanup of
orphaned files, you'll need to handle it yourself (for instance, with a custom
management command that can be run manually or scheduled to run periodically
via e.g. cron).
PasswordInput default rendering behavior PasswordInput default rendering behavior
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -61,11 +61,10 @@ class FileTests(TestCase):
cache.set("obj2", obj2) cache.set("obj2", obj2)
self.assertEqual(cache.get("obj2").normal.name, "tests/django_test_1.txt") self.assertEqual(cache.get("obj2").normal.name, "tests/django_test_1.txt")
# Deleting an object deletes the file it uses, if there are no other # Deleting an object does not delete the file it uses.
# objects still using that file.
obj2.delete() obj2.delete()
obj2.normal.save("django_test.txt", ContentFile("more content")) obj2.normal.save("django_test.txt", ContentFile("more content"))
self.assertEqual(obj2.normal.name, "tests/django_test_1.txt") self.assertEqual(obj2.normal.name, "tests/django_test_2.txt")
# Multiple files with the same name get _N appended to them. # Multiple files with the same name get _N appended to them.
objs = [Storage() for i in range(3)] objs = [Storage() for i in range(3)]