If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!


  • 0
    cfhowes  11 years ago
    So i did some more work, and learned some more things: - i think in the above there are some errors - it seems that you have to parse the field into the blob_info object before you call form.accept. at least when i made some changes to my code today it was broken until i moved that. - i also created a single function that self-posts for the image work, i've included that below. I learned that when i wanted to customize the form with a sub-set of fields my function above was not quite generic enough. here is my custom form function: (lightly tested, so there might be some bugs)
    @auth.requires_login()
    def upload_art():
      """
      This is where an artist uploads a work of art.
      """
      form = SQLFORM(db.artwork,
                     fields=['title',
                             'type',
                             'completed_date',
                             'image'])
    
      if request.env.web2py_runtime_gae:
        from google.appengine.ext import blobstore
        import uuid
        #get the blob_info.  NOTE this MUST be done before any other operations on
        # the request vars.  otherwise something modifies them (perhaps the form
        # validators) in a way that makes this not work
        blob_info = None
        if request.vars.image != None:
            blob_info = blobstore.parse_blob_info(request.vars.image)
    
        upload_url = blobstore.create_upload_url(URL(r=request,f='upload_art',
                                                     args=request.args))
    
        form['_action']=upload_url
        if form.accepts(request.vars,session, formname="artworkform"):
            #@TODO: can this blob-key update be a post-validation function?
            #get the record we just inserted/modified
            row = db(db.artwork.id == form.vars.id).select().first()
            if request.vars.image__delete == 'on' or \
                (form.vars.image != None and (row and row.blob_key)):
                #remove from blobstore because of delete or update of image
                key = row.blob_key
                blobstore.delete(key)
                #remove reference in the artwork record
                row.update_record(blob_key=None, image=None)
            if form.vars.image != None:
                #add reference to image in this record
                row.update_record(image = \
                    "artwork.image."+str(uuid.uuid4()).replace('-','')+".jpg",
                    blob_key = blob_info.key())
            crud.archive(form)
            #Raise the HTTP exception so that the response content stays empty.
            #calling redirect puts content in the body which fails the blob upload
            raise HTTP(303,
                       Location= URL(r=request,f='index'))
        elif form.errors:
            #logging.info("form not accepted")
            logging.info(form.errors)
            session.flash=BEAUTIFY(form.errors)
            #there was an error, let's delete the newly uploaded image
            if request.vars.image != None:
                blobstore.delete(blob_info.key())
            #Raise the HTTP exception so that the response content stays empty.
            #calling redirect puts content in the body which fails the blob upload
            raise HTTP(303,
                       Location= URL(r=request,f='upload_art'))
    
      return dict(form=form)
    

Commented on:

Describes how to use the Google blobstore API, allowing files up to 50MB to be used when a web2py project is hosted on Google App Engine

Hosting graciously provided by:
Python Anywhere