Index: django/core/files/storage.py
===================================================================
--- django/core/files/storage.py	(revision 10691)
+++ django/core/files/storage.py	(working copy)
@@ -1,6 +1,7 @@
 import os
 import errno
 import urlparse
+import itertools
 
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
@@ -63,15 +64,20 @@
         Returns a filename that's free on the target storage system, and
         available for new content to be written to.
         """
-        # If the filename already exists, keep adding an underscore to the name
-        # of the file until the filename doesn't exist.
-        while self.exists(name):
+        # If the filename already exists, add a number to the filename
+        # until an available name is found.
+        if self.exists(name):
+            # Build a filename template out of the (existing) name
             try:
                 dot_index = name.rindex('.')
             except ValueError: # filename has no dot
-                name += '_'
+                template = "%s_%%d" % (name,)
             else:
-                name = name[:dot_index] + '_' + name[dot_index:]
+                template = "%s_%%d%s" % (name[:dot_index], name[dot_index:],)
+            # Iterate indefinitely until a filename is found.
+            count = itertools.count(1)
+            while self.exists(name):
+                name = template % count.next()
         return name
 
     def path(self, name):
Index: tests/modeltests/files/models.py
===================================================================
--- tests/modeltests/files/models.py	(revision 10691)
+++ tests/modeltests/files/models.py	(working copy)
@@ -88,12 +88,18 @@
 >>> '-'.join(obj1.normal.chunks(chunk_size=2))
 'co-nt-en-t'
 
-# Save another file with the same name.
+# Save more files with the same name; check for _[x] appendix.
 
+>>> objs = [ Storage() for i in range(10) ]
+>>> count = 1
+>>> for o in objs: 
+...     o.normal.save('django_test.txt', ContentFile('Ten files, same content'))
+>>> map(lambda o: o.normal, objs)
+[<FieldFile: tests/django_test_1.txt>, <FieldFile: tests/django_test_2.txt>, <FieldFile: tests/django_test_3.txt>, <FieldFile: tests/django_test_4.txt>, <FieldFile: tests/django_test_5.txt>, <FieldFile: tests/django_test_6.txt>, <FieldFile: tests/django_test_7.txt>, <FieldFile: tests/django_test_8.txt>, <FieldFile: tests/django_test_9.txt>, <FieldFile: tests/django_test_10.txt>]
+>>> for o in objs: o.delete()
+
 >>> obj2 = Storage()
 >>> obj2.normal.save('django_test.txt', ContentFile('more content'))
->>> obj2.normal
-<FieldFile: tests/django_test_.txt>
 >>> obj2.normal.size
 12
 
@@ -102,7 +108,7 @@
 >>> cache.set('obj1', obj1)
 >>> cache.set('obj2', obj2)
 >>> cache.get('obj2').normal
-<FieldFile: tests/django_test_.txt>
+<FieldFile: tests/django_test_1.txt>
 
 # Deleting an object deletes the file it uses, if there are no other objects
 # still using that file.
@@ -110,7 +116,7 @@
 >>> obj2.delete()
 >>> obj2.normal.save('django_test.txt', ContentFile('more content'))
 >>> obj2.normal
-<FieldFile: tests/django_test_.txt>
+<FieldFile: tests/django_test_1.txt>
 
 # Default values allow an object to access a single file.
 
Index: tests/regressiontests/file_storage/tests.py
===================================================================
--- tests/regressiontests/file_storage/tests.py	(revision 10691)
+++ tests/regressiontests/file_storage/tests.py	(working copy)
@@ -121,9 +121,9 @@
         name = self.save_file('conflict')
         self.thread.join()
         self.assert_(self.storage.exists('conflict'))
-        self.assert_(self.storage.exists('conflict_'))
+        self.assert_(self.storage.exists('conflict_1'))
         self.storage.delete('conflict')
-        self.storage.delete('conflict_')
+        self.storage.delete('conflict_1')
 
 class FileStoragePermissions(TestCase):
     def setUp(self):
