Sunday, March 28, 2010

BlobStore upload with django form validation Example

This is my current approach to handle blobstore uploads that also need a django form validation.

You can find the get_uploads helper function here: blobstore get_uploads helper function for django request

I tried to do the example as simple as possible, but complete. This may not be perfect, all comments are welcome.

Seba


#### core/models.py ####

from google.appengine.ext import blobstore
from google.appengine.ext import db

class PhotoItem(db.Model):
    name = db.StringProperty()
    photo = blobstore.BlobReferenceProperty()

#### core/forms.py ####

from django import forms

class PhotoForm(forms.Form):
    name = forms.CharField(required=True)


##### core/views.py ####

from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext

from google.appengine.ext import blobstore

from core.models import PhotoItem
from core.forms import PhotoForm
from core.utils import get_uploads

def upload_photo(request):
    if request.method == 'POST':
        photo_blobs = get_uploads(request, field_name="photo", populate_post=True)
        form = PhotoForm(request.POST)
        if form.is_valid() and len(photo_blobs) == 1:
            photo_item = PhotoItem(name=form.cleaned_data['name'],
                                   photo=photo_blobs[0])
            photo_item.put()
            
            return HttpResponseRedirect("/success")
        
        #ok, not valid
        if len(photo_blobs) == 0:
            #the file input is missing
            request.session['upload_error'] = "Photo is required"
            
        #save the post data in the session to be able to present errors after redirect
        request.session['upload_form_post'] = request.POST
        return HttpResponseRedirect(reverse("core.views.upload_photo"))
    elif request.session.has_key('upload_form_post'):
        form = PhotoForm(request.session['upload_form_post'])
        del request.session['upload_form_post']
    else:
        form = PhotoForm()
    
    params = {
        'upload_url': blobstore.create_upload_url(reverse("core.views.upload_photo")),
        'form': form,
        'upload_error': request.session.pop('upload_error', None)
    }
    
    return render_to_response("upload_photo.html", 
                              params,
                              RequestContext(request))

#### Example upload_photo.html ####
{% extends "base.html" %}

{% block main_content %}
    <h1>Upload Photo</h1>
    
    {% if upload_error %}
    <div class="error">{{ upload_error }}</div>
    {% endif %}
    <form action="{{ upload_url }}" method="post" 
                  enctype="multipart/form-data">
    <ul>
        {{ form.as_ul }}
        <li><input type="file" name="photo"/></li>
        <li><input type="submit"/></li>
    </ul>
    </form>
{% endblock %}

Notes

  1. sserrano posted this