Google App Engine (Python) - Uploading a file (

2019-02-02 01:26发布

I want the user to be able to upload images to Google App Engine. I have the following (Python):

class ImageData(ndb.Model):
     name = ndb.StringProperty(indexed=False)
     image = ndb.BlobProperty()

Information is submitted by the user using a form (HTML):

<form name = "input" action = "/register" method = "post">
    name: <input type = "text" name = "name">
    image: <input type = "file" name = "image">
</form>

Which is then processed by:

class AddProduct(webapp2.RequestHandler):
    def post(self):
        imagedata = ImageData(parent=image_key(image_name))
        imagedata.name = self.request.get('name')
        imagedata.image = self.request.get('image')
        imagedata.put()

However, when I try to upload an image, lets say "Book.png", I get the error: BadValueError: Expected str, got u'Book.png'

Any idea what is going on? I have been working with GAE for quite some time, but this is the first time I had to use blobs.

I used this link: https://developers.google.com/appengine/docs/python/images/usingimages which uses db, not ndb. I also tried storing the image in a variable first like in the link: storedInfo = self.request.get('image') and then storing it: imagedata.image = ndb.Blob(storedInfo) Which ALSO gives me an error: AttributeError: 'module' object has no attribute 'Blob' Thanks in advance.

3条回答
干净又极端
2楼-- · 2019-02-02 01:52

There is a great example in the documentation that describes how to upload files to the Blobstore using a HTML form: https://developers.google.com/appengine/docs/python/blobstore/#Python_Uploading_a_blob

The form should point to a url generated by blobstore.create_upload_url('/foo') and there should be a subclass of the BlobstoreUploadHandler at /foo like this:

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    upload_files = self.get_uploads('file')
    blob_info = upload_files[0]
    imagedata = ImageData(parent=image_key(image_name))
    imagedata.name = self.request.get('name')
    imagedata.image = blob_info.key()
    imagedata.put()

For this to work, you should change your data model such that in ImageData, image referes to a ndb.BlobKeyProperty().

You can serve your image simply from a url generated by images.get_serving_url(imagedata.image), optionally resized and cropped.

查看更多
We Are One
3楼-- · 2019-02-02 01:58

Had the same prob.

just replace

imagedata.image = self.request.get('image')

with:

imagedata.image = str(self.request.get('image'))

also your form needs to have enctype="multipart/form-data

<form name = "input" action = "/register" method = "post" enctype="multipart/form-data">
查看更多
成全新的幸福
4楼-- · 2019-02-02 01:59

You must add enctype="multipart/form-data" to your form in order for this to work

<form name = "input" action = "/register" method = "post" enctype="multipart/form-data">
    name: <input type = "text" name = "name">
    image: <input type = "file" name = "image">
</form>
查看更多
登录 后发表回答