Index: django/db/models/fields/files.py
===================================================================
--- django/db/models/fields/files.py	(revision 9050)
+++ django/db/models/fields/files.py	(working copy)
@@ -55,8 +55,10 @@
     url = property(_get_url)
 
     def _get_size(self):
-        self._require_file()
-        return self.storage.size(self.name)
+        if not hasattr(self, '_size'):
+            self._require_file()
+            self._size = self.storage.size(self.name)
+        return self._size
     size = property(_get_size)
 
     def open(self, mode='rb'):
@@ -74,8 +76,9 @@
         self._name = self.storage.save(name, content)
         setattr(self.instance, self.field.name, self.name)
 
-        # Update the filesize cache
-        self._size = len(content)
+        # Delete the filesize cache
+        if hasattr(self, '_size'):
+            del self._size
 
         # Save the object because it has changed, unless save is False
         if save:
@@ -205,17 +208,19 @@
 
 class ImageFieldFile(ImageFile, FieldFile):
     def save(self, name, content, save=True):
-        # Repopulate the image dimension cache.
-        self._dimensions_cache = get_image_dimensions(content)
+        
+        # Clear the image dimensions cache
+        if hasattr(self, '_dimensions_cache'):
+            del self._dimensions_cache
 
+        super(ImageFieldFile, self).save(name, content, save)
+        
         # Update width/height fields, if needed
         if self.field.width_field:
             setattr(self.instance, self.field.width_field, self.width)
         if self.field.height_field:
             setattr(self.instance, self.field.height_field, self.height)
 
-        super(ImageFieldFile, self).save(name, content, save)
-
     def delete(self, save=True):
         # Clear the image dimensions cache
         if hasattr(self, '_dimensions_cache'):
Index: django/core/files/storage.py
===================================================================
--- django/core/files/storage.py	(revision 9050)
+++ django/core/files/storage.py	(working copy)
@@ -150,15 +150,19 @@
                     file_move_safe(content.temporary_file_path(), full_path)
                     content.close()
 
-                # This is a normal uploadedfile that we can stream.
                 else:
                     # This fun binary flag incantation makes os.open throw an
                     # OSError if the file already exists before we open it.
                     fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0))
                     try:
                         locks.lock(fd, locks.LOCK_EX)
+                        # first try accessing content as an uploadedfile
                         for chunk in content.chunks():
                             os.write(fd, chunk)
+                    except AttributeError:
+                        # try reading the content using the read method
+                        data = content.read()
+                        os.write(fd, data)  
                     finally:
                         locks.unlock(fd)
                         os.close(fd)
Index: tests/modeltests/files/models.py
===================================================================
--- tests/modeltests/files/models.py	(revision 9050)
+++ tests/modeltests/files/models.py	(working copy)
@@ -6,6 +6,7 @@
 """
 
 import tempfile
+from urllib2 import urlopen
 
 from django.db import models
 from django.core.files.base import ContentFile
@@ -32,6 +33,8 @@
     random = models.FileField(storage=temp_storage, upload_to=random_upload_to)
     default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt')
 
+    image = models.ImageField(storage=temp_storage, upload_to='tests')
+    
 __test__ = {'API_TESTS':"""
 # An object without a file has limited functionality.
 
@@ -109,10 +112,25 @@
 >>> obj4.random
 <FieldFile: .../random_file>
 
+# testing urllib
+
+>>> obj5 = Storage()
+>>> image_data_len = len(urlopen('http://media.djangoproject.com/img/badges/djangosite80x15.gif').read())
+>>> obj5.image.save('django_logo.gif',urlopen('http://media.djangoproject.com/img/badges/djangosite80x15.gif'))
+>>> obj5.image
+<ImageFieldFile: tests/django_logo.gif>
+>>> image_data_len == obj5.image.size
+True
+>>> obj5.image.width
+80L
+>>> obj5.image.height
+15L
+
 # Clean up the temporary files.
 
 >>> obj1.normal.delete()
 >>> obj2.normal.delete()
 >>> obj3.default.delete()
 >>> obj4.random.delete()
+>>> obj5.image.delete()
 """}
