Hi,

It didn't seem like any of the current Django file upload apps provided exactly 
the functionality I needed, so I hacked my own.  If the community is 
interested, I can try to polish it a bit and contribute it.

We deal with large uploads - up to hundreds of megabytes - so I wanted the 
following:

-the server should not keep the whole file in memory while the upload is 
progressing: it should stream to disk

-the server shouldn't have to copy the streamed data: it should only write the 
uploaded file once

-the user must get some feedback (a progress meter, or whatever) while the 
upload is progressing


I wrote some code that accomplishes this.  You can see an ugly demo at:
http://oven.cosmo.fas.nyu.edu:8888/upload-demo/

It works as follows:

-There is a python CGI program that accepts the upload.  It's not a Django view 
because it needs to stream the input as it comes in from the network; it runs 
as a normal mod_python handler.

-This CGI program parses the multipart/form-data input, looking for an 
"upload_id" field (which tells it which temp file to write the uploaded file 
to), and then looks for the file data itself and streams that to disk.  At the 
end of the upload, it produces a dictionary of the "normal" form fields and an 
object representing the uploaded file.

-We have a "main" form with several fields, and within that HTML page there are 
two IFRAMEs.  The first one contains an "upload" form: it requests a form which 
has a hidden "upload_id" field and a file input element (and a hidden submit 
button).  The second IFRAME contains an (initially hidden) upload progress 
meter.

-If the user submits the "upload" form (by hitting ENTER in the file input 
dialog), some Javascript gets triggered which displays the upload progress 
meter.  (The upload progress meter is a snazzy little AJAX dealie - quite nice 
but its CSS needs some attention).  If the file is empty or some other error 
occurs, the progress meter shows an error message.

-When the file upload starts, the CGI writes "Upload in progress..." and when 
if it finishes successfully, it writes a hidden <div> element.  Some Javascript 
notices that the upload form's IFRAME finished loading, and it looks for that 
<div> to ensure that the upload was successful.  If so, it grabs the 
"upload_id", saves it in a hidden field in the main form, and submits the main 
form.

-The main form goes to a normal Django view, and it can use the "upload_id" to 
pull a reference to the file out of a database.


I know it sounds overly complicated, but it seemed to be necessary to achieve 
the user experience and server-side requirements I had.

Before it's ready for prime-time, it will need some fixes:

-the form-multipart parsing is currently hacky; the RFC should get translated 
into regular expressions

-the upload form handler currently doesn't really do anything with the other 
form fields - it should store them in a database.

-there's not a lot of checking of upload_id values - one could easily add some 
rules that only upload_ids that have been generated by the server can be 
uploaded; and that it's invalid to try to re-upload a file; or that only 
authenticated users are allowed to upload files.

-I'm new to python and Django, so I'm sure there is a lot of polishing that 
could be done.

-I tried to work out a solution that didn't require two IFRAMES (one for the 
file form, one for the progress meter), but couldn't get it to work.


Anyway, let me know if you're interested in this code and I'll bundle it up if 
anyone is.

Cheers,
dstn.


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

Reply via email to