Browse Source

Fixed #22772 -- Defer wizard temporary files deletion.

Simon Charette 10 years ago
parent
commit
e2112edd9a

+ 2 - 1
django/contrib/formtools/tests/wizard/storage.py

@@ -3,7 +3,7 @@ from importlib import import_module
 import os
 import tempfile
 
-from django.http import HttpRequest
+from django.http import HttpRequest, HttpResponse
 from django.conf import settings
 from django.contrib.auth.models import User
 from django.core.files.storage import FileSystemStorage
@@ -107,4 +107,5 @@ class TestStorage(object):
         self.assertTrue(storage.file_storage.exists(tmp_name))
 
         storage.reset()
+        storage.update_response(HttpResponse())
         self.assertFalse(storage.file_storage.exists(tmp_name))

+ 7 - 2
django/contrib/formtools/wizard/storage/base.py

@@ -17,6 +17,7 @@ class BaseStorage(object):
         self.request = request
         self.file_storage = file_storage
         self._files = {}
+        self._tmp_files = []
 
     def init_data(self):
         self.data = {
@@ -27,11 +28,13 @@ class BaseStorage(object):
         }
 
     def reset(self):
-        # Delete temporary files before breaking reference to them.
+        # Store unused temporary file names in order to delete them
+        # at the end of the response cycle through a callback attached in
+        # `update_response`.
         wizard_files = self.data[self.step_files_key]
         for step_files in six.itervalues(wizard_files):
             for step_file in six.itervalues(step_files):
-                self.file_storage.delete(step_file['tmp_name'])
+                self._tmp_files.append(step_file['tmp_name'])
         self.init_data()
 
     def _get_current_step(self):
@@ -118,6 +121,8 @@ class BaseStorage(object):
             for file in self._files.values():
                 if not file.closed:
                     file.close()
+            for tmp_file in self._tmp_files:
+                self.file_storage.delete(tmp_file)
 
         if hasattr(response, 'render'):
             response.add_post_render_callback(post_render_callback)