There is ticket (and a patch) for enabling streaming uploads, but it
seemed a little complicated and until it gets accepted (or reworked)
here is nice workaround to do the same. See patch at the end.

It is backward compatible, the current behavior stays the same, you
can use still request.FILES to get the dictionary keyed by file names.
When you first access request.FILES it loads everything into memory.
Now for large files you can use request.STREAM to get a file handle on
the input. Note that in this latter case you'll need to do some simple
parsing to get your file.

The patch itself is only 5 lines, but I've changed a few method names
to be more consistent.

Istvan


Index: wsgi.py
===================================================================
--- wsgi.py     (revision 4455)
+++ wsgi.py     (working copy)
@@ -5,6 +5,7 @@
 from django import http
 from pprint import pformat
 from shutil import copyfileobj
+import tempfile
 try:
     from cStringIO import StringIO
 except ImportError:
@@ -108,12 +109,13 @@
     def _load_post_and_files(self):
         # Populates self._post and self._files
         if self.method == 'POST':
+            buffer = self.STREAM.read()
             if self.environ.get('CONTENT_TYPE',
'').startswith('multipart'):
                 header_dict = dict([(k, v) for k, v in
self.environ.items() if k.startswith('HTTP_')])
                 header_dict['Content-Type'] =
self.environ.get('CONTENT_TYPE', '')
-                self._post, self._files =
http.parse_file_upload(header_dict, self.raw_post_data)
+                self._post, self._files =
http.parse_file_upload(header_dict, buffer )
             else:
-                self._post, self._files =
http.QueryDict(self.raw_post_data), datastructures.MultiValueDict()
+                self._post, self._files = http.QueryDict( buffer ),
datastructures.MultiValueDict()
         else:
             self._post, self._files = http.QueryDict(''),
datastructures.MultiValueDict()

@@ -152,9 +154,10 @@
             self._load_post_and_files()
         return self._files

-    def _get_raw_post_data(self):
+    def _get_post_stream(self):
         try:
-            return self._raw_post_data
+            self._stream.seek(0)
+            return self._stream
         except AttributeError:
             buf = StringIO()
             try:
@@ -162,18 +165,19 @@
                 content_length =
int(self.environ.get('CONTENT_LENGTH', 0))
             except ValueError: # if CONTENT_LENGTH was empty string
or not an integer
                 content_length = 0
-            safe_copyfileobj(self.environ['wsgi.input'], buf,
size=content_length)
-            self._raw_post_data = buf.getvalue()
-            buf.close()
-            return self._raw_post_data
+
+            self._stream = tempfile.TemporaryFile()
+            safe_copyfileobj(self.environ['wsgi.input'],
self._stream, size=content_length)
+            self._stream.seek(0)
+            return self._stream

     GET = property(_get_get, _set_get)
     POST = property(_get_post, _set_post)
     COOKIES = property(_get_cookies, _set_cookies)
     FILES = property(_get_files)
     REQUEST = property(_get_request)
-    raw_post_data = property(_get_raw_post_data)
-
+    STREAM  = property(_get_post_stream)
+
 class WSGIHandler(BaseHandler):
     def __call__(self, environ, start_response):
         from django.conf import settings


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to