1

I have a form in google app engine where I want to upload an image and all my text at the same time. Do I have to seperate this into two seperate pages and actions?

Here is my upload handler:

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def upload(self, reseller_id, imgfile):
        upload_files = imgfile
        blob_info = upload_files[0]
        key = blob_info.key()
        r = Reseller.get_by_id(reseller_id)
        r.blob_key_logo = str(key)
        r.put();

Here is my creation of a new reseller object:

class NewReseller(BaseHandler):
    def get(self):
        if self.user:
            self.render("new_reseller.html")
        else:
            self.redirect("/display_resellers")

    def post(self):
        name = self.request.get('name')
        website = self.request.get('website')
        information = self.request.get('information')
        address = self.request.get('address')
        city = self.request.get('city')
        state = self.request.get('state')
        zipcode = self.request.get('zipcode')
        email = self.request.get('email')
        phone = self.request.get('phone')

        r = Reseller( name = name, 
              website = website, 
              information = information, 
              address = address,
              city = city,
              state = state,
              zipcode = zipcode,
              email = email, 
              phone = phone)        
        r.put()

        theresellerid = r.key().id()
        #And then Upload the image
        u = UploadHandler()
        logo_img = u.get_uploads('logo_img')
        u.upload(theid, logo_img)

        self.redirect('/display_resellers')

I think my problem here is this line:

logo_img = u.get_uploads('logo_img')

it pops out the error message

for key, value in self.request.params.items():
AttributeError: 'NoneType' object has no attribute 'params'

Somehow I need this NewReseller class to inherit the .getuploads from BlobstoreUploadHandler so I can do:

   logo_img = self.get_uploads('logo_img')

Or there is probably a better way because this seems a little messy.

So my question is how to upload files and data in one form on just one page. I could do it with two seperate pages. One for adding the reseller and one for adding the image but that seems over complicated.

I tried to follow some steps and clues from this question:

Upload files in Google App Engine

******Edit***** Working Implementation Below:

class EditReseller(BaseHandler, blobstore_handlers.BlobstoreUploadHandler):
    def get(self, reseller_id):
        if self.user:
            reseller = Reseller.get_by_id(int(reseller_id))
            upload_url = blobstore.create_upload_url('/upload')
            image = True
            if reseller.blob_key_logo is None:
                image = False
            self.render('edit_reseller.html', r=reseller, reseller_id=reseller_id, upload_url=upload_url, image=image)

        else:
            self.redirect('/admin')


class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self):
        reseller_id = self.request.get('reseller_id')
        upload_files = self.get_uploads('logo_img')
        if upload_files:
            blob_info = upload_files[0]
            key = blob_info.key()
            r = Reseller.get_by_id(int(reseller_id))
            r.blob_key_logo = str(key)
            r.put();

        name = self.request.get('name')
        website = self.request.get('website')
        information = self.request.get('information')
        address = self.request.get('address')
        city = self.request.get('city')
        state = self.request.get('state')
        zipcode = self.request.get('zipcode')
        email = self.request.get('email')
        phone = self.request.get('phone')

        if name and website and information and email and phone and address and city and state and zipcode:
            r = Reseller.get_by_id(int(reseller_id))
            r.name = name 
            r.website = website
            r.information = information
            r.address = address
            r.city = city
            r.state = state
            r.zipcode = zipcode
            r.email = email
            r.phone = phone
            r.put()

        else:
            error = "Looks like your missing some critical info"
            self.render("edit_reseller.html", name=name, website=website, information=information, address=address, city=city, zipcode=zipcode, email=email, phone=phone, error=error)


        self.redirect("/edit_reseller/" + reseller_id)
Community
  • 1
  • 1
ChickenFur
  • 2,360
  • 3
  • 20
  • 26

1 Answers1

2

You just need to put the logic of the UploadHandler inside the Reseller(BaseHandler) and make Reseller inherit from blobstore_handlers.BlobstoreUploadHandler.

The call to get_uploads fails, as the NewReseller Class does not inherit from BlobstoreUploadHandler. The BlobstoreUploadHandler class takes over the upload operation so you do not need to create a post method, just add the corresponding logic from post ( name = self.request.get('name'), r = Reseller(), r.put(), etc. ) and add it to the upload method.

You should not call or create a new a handler instance by hand (unless you know what you are doing), as it would be missing the things that make it work.

The complete app sample at the official docs, might also be helpful.

  • Thank You. I changed the EditReseller Class to inherit from my base handler and blobstore_handlers.BlobstoreUploadHandler and moved the entire post method to the upload handler. – ChickenFur Jun 19 '12 at 18:24