Ticket #4948: safe_filename_gen.1.2.diff
File safe_filename_gen.1.2.diff, 6.5 KB (added by , 17 years ago) |
---|
-
django/db/models/base.py
380 380 pass 381 381 filename = field.get_filename(filename) 382 382 383 # If the filename already exists, keep adding an underscore to the name of384 # the file until the filename doesn't exist.385 while os.path.exists(os.path.join(settings.MEDIA_ROOT, filename)):383 # Generate a unique filename 384 while True: 385 full_filename = os.path.join(settings.MEDIA_ROOT, filename) 386 386 try: 387 # Try and open our filename, but only if it doesn't exist 388 # and we can open it exclusively. This won't necessarily work on 389 # NFS and some other networked filesystems, but will be ok in normal 390 # cases. 391 fd = os.open(full_filename, os.O_RDWR | os.O_CREAT | os.O_EXCL) 392 break; 393 except OSError, e: 394 # Someone else grabbed this name already 395 pass 396 397 # If the filename already exists, keep adding an underscore to the name of 398 # the file until the filename doesn't exist. 399 try: 387 400 dot_index = filename.rindex('.') 388 401 except ValueError: # filename has no dot 389 402 filename += '_' … … 393 406 # Write the file to disk. 394 407 setattr(self, field.attname, filename) 395 408 396 full_filename = self._get_FIELD_filename(field) 397 fp = open(full_filename, 'wb') 409 fp = os.fdopen(fd, 'w+b') 398 410 fp.write(raw_contents) 399 411 fp.close() 400 412 -
tests/regressiontests/file_field/tests.py
1 1 """ 2 Tests for file field behavior, and specifically #639, in which Model.save() gets 3 called *again* for each FileField. This test will fail if calling an 4 auto-manipulator's save() method causes Model.save() to be called more than once. 2 Tests for file field behavior. 5 3 """ 6 4 import tempfile 7 5 import os 6 import shutil 8 7 import unittest 9 from regressiontests. bug639.models import Photo8 from regressiontests.file_field.models import Photo 10 9 from django.http import QueryDict 11 10 from django.utils.datastructures import MultiValueDict 11 from django.conf import settings 12 12 13 class Bug639Test(unittest.TestCase): 14 13 class FileFieldTests(unittest.TestCase): 14 def setUp(self): 15 self.img_content = open(os.path.join(os.path.dirname(__file__), "test.jpg"), "rb").read() 16 self.old_media_root = settings.MEDIA_ROOT 17 settings.MEDIA_ROOT = tempfile.gettempdir() 18 15 19 def testBug639(self): 16 20 """ 17 21 Simulate a file upload and check how many times Model.save() gets called. 22 23 #639, in which Model.save() gets called *again* for each FileField. This 24 test will fail if calling an auto-manipulator's save() method causes 25 Model.save() to be called more than once. 18 26 """ 19 27 # Grab an image for testing 20 img = open(os.path.join(os.path.dirname(__file__), "test.jpg"), "rb").read()21 28 22 29 # Fake a request query dict with the file 23 30 qd = QueryDict("title=Testing&image=", mutable=True) 24 31 qd["image_file"] = { 25 32 "filename" : "test.jpg", 26 33 "content-type" : "image/jpeg", 27 "content" : img34 "content" : self.img_content 28 35 } 29 36 30 37 manip = Photo.AddManipulator() … … 34 41 # Check the savecount stored on the object (see the model) 35 42 self.assertEqual(p._savecount, 1) 36 43 44 def testFilenameGeneration_unique(self): 45 """ 46 Make sure we're generating unique filenames. 47 Note that upload_to is set to 'file_field_test' 48 """ 49 50 p0 = Photo(title="test0") 51 p0.save_image_file('testfg0.jpg', self.img_content) 52 self.assert_(os.path.exists(p0.get_image_filename())) 53 self.assertEqual(p0.image, os.path.normpath("file_field_test/testfg0.jpg")) 54 # Second file should have an '_' before the extension 55 p1 = Photo(title="test1") 56 p1.save_image_file('testfg0.jpg', self.img_content) 57 self.assert_(os.path.exists(p1.get_image_filename())) 58 self.assertNotEqual(p0.image, p1.image) 59 self.assertEqual(p1.image, os.path.normpath("file_field_test/testfg0_.jpg")) 60 61 # Now test with no extension 62 p2 = Photo(title="test2") 63 p2.save_image_file('testfg1', self.img_content) 64 self.assert_(os.path.exists(p2.get_image_filename())) 65 self.assertEqual(p2.image, os.path.normpath("file_field_test/testfg1")) 66 # Second file should have an '_' 67 p3 = Photo(title="test1") 68 p3.save_image_file('testfg1', self.img_content) 69 self.assert_(os.path.exists(p3.get_image_filename())) 70 self.assertNotEqual(p2.image, p3.image) 71 self.assertEqual(p3.image, os.path.normpath("file_field_test/testfg1_")) 72 73 def testFileSaving(self): 74 "Test we actually put the content into the file" 75 p = Photo(title="test") 76 p.save_image_file('tests0.jpg', self.img_content) 77 self.assert_(os.path.exists(p.get_image_filename())) 78 saved_img = open(p.get_image_filename(), 'rb').read() 79 self.assertEqual(self.img_content, saved_img) 80 37 81 def tearDown(self): 38 82 """ 39 Make sure to delete the "uploaded" file to avoid clogging /tmp.83 Make sure to delete the "uploaded" files to avoid clogging /tmp. 40 84 """ 41 p = Photo.objects.get() 42 os.unlink(p.get_image_filename()) 43 No newline at end of file 85 shutil.rmtree(os.path.join(settings.MEDIA_ROOT, 'file_field_test')) 86 settings.MEDIA_ROOT = self.old_media_root -
tests/regressiontests/file_field/models.py
1 import tempfile2 1 from django.db import models 3 2 4 3 class Photo(models.Model): 5 4 title = models.CharField(max_length=30) 6 image = models.FileField(upload_to= tempfile.gettempdir())5 image = models.FileField(upload_to='file_field_test') 7 6 8 7 # Support code for the tests; this keeps track of how many times save() gets 9 8 # called on each instance.