GAE Blobstore is a great way to manage big files. This post is about using the Blogstore with Python and the Django GAE Helper (appengine_django).

Views.py:


from google.appengine.ext import blobstore
# import other django stuff

def show_upload_form(request):
    template = "admin_upload_blob.html"
    dict = {}
    dict['action'] = blobstore.create_upload_url('/admin/upload_blob/')
    return render_to_response(template, 
                context_instance= context.get_context(
                            dict, request))
    
def upload_blob(request):
    try:
        uploads = get_uploads(request, 'file')
        for upload in uploads:
            file = BlobFile(blob=upload)
            file.save()
    except Exception, e:
        return HttpResponseRedirect("/admin")
    return HttpResponse("Ok!")


def get_uploads(request, field_name=None, populate_post=False):
    """
    http://appengine-cookbook.appspot.com/recipe/blobstore-get_uploads-helper-function-for-django-request/
    
    Get uploads sent to this handler.
    
    Args:
    field_name: Only select uploads that were sent as a specific field.
    populate_post: Add the non blob fields to request.POST
    
    Returns:
    A list of BlobInfo records corresponding to each upload.
    Empty list if there are no blob-info records for field_name.
    """
    
    logging.info(request)
    if hasattr(request,'__uploads') == False:
        request.META['wsgi.input'].seek(0)
        fields = cgi.FieldStorage(request.META['wsgi.input'], environ=request.META)
        
        request.__uploads = {}
        if populate_post:
            request.POST = {}
        for key in fields.keys():
            field = fields[key]
            if isinstance(field, cgi.FieldStorage) and 'blob-key' in field.type_options:
                request.__uploads.setdefault(key, []).append(blobstore.parse_blob_info(field))
            elif populate_post:
                request.POST[key] = field.value

    if field_name:
        try:
            return list(request.__uploads[field_name])
        except KeyError:
            return []
    else:
        results = []
        for uploads in request.__uploads.itervalues():
            results += uploads
        return results

admin_upload_blob.html:

{% extends "base.html" %}
{% load i18n %}

{% block content %}

Upload a big file: 

Upload File:
{% endblock content %}

Make sure urls.py contains the methods in views.py as usual.
Just access show_upload_form with your browser and upload a file. It works!