summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Meyer <carl@oddbird.net>2011-01-26 08:04:19 +0000
committerCarl Meyer <carl@oddbird.net>2011-01-26 08:04:19 +0000
commit3af1bf8217653f4e5ed337957607835e3f146039 (patch)
tree52e30b4b692d5f31965f52b5aff9fa59920bfbee
parentc4b0878b4389f466d90ac458872df7ba28706023 (diff)
[1.2.X] Fixed #6456 - Excised FileField file deletion to avoid data loss. Thanks to durdinator for the report.
Backport of r15321 from trunk. Backported despite slight backwards-incompatibility due to potential for data loss. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15322 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/models/fields/files.py13
-rw-r--r--docs/releases/1.2.5.txt23
-rw-r--r--tests/modeltests/files/tests.py5
3 files changed, 22 insertions, 19 deletions
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index e51f4441c5..28f25252d2 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -258,19 +258,6 @@ class FileField(Field):
def contribute_to_class(self, cls, name):
super(FileField, self).contribute_to_class(cls, name)
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):
return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to))))
diff --git a/docs/releases/1.2.5.txt b/docs/releases/1.2.5.txt
index d8efb9d607..cfdaeaa94e 100644
--- a/docs/releases/1.2.5.txt
+++ b/docs/releases/1.2.5.txt
@@ -7,7 +7,7 @@ Welcome to Django 1.2.5!
This is the fifth "bugfix" release in the Django 1.2 series,
improving the stability and performance of the Django 1.2 codebase.
-With one exception, Django 1.2.5 maintains backwards compatibility
+With two exceptions, Django 1.2.5 maintains backwards compatibility
with Django 1.2.4, but contain a number of fixes and other
improvements. Django 1.2.5 is a recommended upgrade for any
development or deployment currently using or targeting Django 1.2.
@@ -15,8 +15,25 @@ development or deployment currently using or targeting Django 1.2.
For full details on the new features, backwards incompatibilities, and
deprecated features in the 1.2 branch, see the :doc:`/releases/1.2`.
-One backwards incompatibility
-=============================
+Backwards incompatible changes
+==============================
+
+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 potentially
+serious data-loss scenarios, including rolled-back transactions and fields on
+different models referencing the same file. In Django 1.2.5,
+: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).
+
+Use of custom SQL to load initial data in tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Django provides a custom SQL hooks as a way to inject hand-crafted SQL
into the database synchronization process. One of the possible uses
diff --git a/tests/modeltests/files/tests.py b/tests/modeltests/files/tests.py
index 025fcc574a..6348d022e2 100644
--- a/tests/modeltests/files/tests.py
+++ b/tests/modeltests/files/tests.py
@@ -58,11 +58,10 @@ class FileTests(TestCase):
cache.set("obj2", obj2)
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
- # objects still using that file.
+ # Deleting an object does not delete the file it uses.
obj2.delete()
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.
objs = [Storage() for i in range(3)]