Google App Engine:在数据库中存储图片(Python)

0 投票
3 回答
3659 浏览
提问于 2025-04-17 20:50

我正在使用Python在Google App Engine上创建一个电商平台。为了这个平台,我需要把我将要提供的产品的详细信息存储在一个单独的实体中,这个实体还需要包含每个产品的图片。那么,我该如何在数据存储中保存这些图片呢?更重要的是,我该如何从数据库中提取图片,并在我的应用程序中展示给用户呢?

编辑:

在我把图片上传到一个叫“Images”的实体后,我尝试去显示它。以下是相关的代码:

main.py

class FileUpload(Handler):
    def post(self):
        file_upload = self.request.POST.get("file", None)
        file_name = file_upload.filename
        image = Images(id=file_name, file_name=file_name, blob=file_upload.file.read())
        image.put()

        self.response.headers[b'Content-Type'] = mimetypes.guess_type(image.file_name)[0]
        self.response.write(image.blob)
        self.final()

    def final(self):
        images = db.GqlQuery("Select * FROM Images WHERE file_name = 'CN.jpg'")
        self.render("template.html", images = images)

class Blob(Handler):
    def get(self):
        self.render("blob.html")


app = webapp2.WSGIApplication([('/', MainPage),
                                ('/signup', Register),
                                ('/login', Login),
                                ('/logout', Logout),
                                ('/mp', MP),
                                (r'/file_upload', FileUpload),
                                ('/blob', Blob)], debug=True)

template.html

<html>
<head>
    <title>Template</title>
</head>
<body>
    {%
        for image in images
    %}
    <div>{{image.blob}}</div>
    {%endfor%}
</body>
</html>

blob.html

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Image Upload</title>
</head>
<body>
<form action="/file_upload" enctype="multipart/form-data" method="post">
    <div><input type="file" name="file"/></div>
    <div><input type="submit" value="Upload"></div>
</form>
</body>
</html>

现在,在template.html中,我原本期待能看到我尝试提取的图片。然而,我却遇到了以下错误:

<div>{{image.blob}}</div>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)

3 个回答

0

有几种选择,你可以根据图片的大小和工作流程来决定使用哪种方式。

  1. 如果这些图片是固定的,只有开发团队会更改它们,你可以把它们作为静态文件放在项目里。
  2. 你可以使用blobstore API来实现图片的上传和查看。
  3. 你也可以使用Google Cloud Storage库来上传和查看图片。我感觉谷歌正在逐渐倾向于使用这个,而不是blobstore。
2

你可以使用谷歌的高性能图片服务。你需要把图片存储或上传到blobstore或者谷歌云存储,然后创建一个服务链接。

这样做的好处有:

  • 性能很高
  • 图片由谷歌来提供,你不需要自己处理这些图片;
  • 费用低廉
  • 可以动态调整大小和裁剪图片。

更多信息:关于如何提供blob的内容可以查看这个链接: https://developers.google.com/appengine/docs/python/blobstore/ 获取服务链接的内容可以查看这个链接: https://developers.google.com/appengine/docs/python/images/functions

6

这是一个简单的例子,展示如何上传一张图片,把它保存在数据存储中,并且提供这张图片的服务。

文件名是 fileupload.py:

import webapp2
from google.appengine.ext import ndb
import mimetypes


class Images(ndb.Model):
    file_name = ndb.StringProperty()
    blob = ndb.BlobProperty()


class FileUpload(webapp2.RequestHandler):

    def post(self):

        file_upload = self.request.POST.get("file", None)
        file_name = file_upload.filename
        image = Images(id=file_name, file_name=file_name, blob=file_upload.file.read())
        image.put()

        self.response.headers[b'Content-Type'] = mimetypes.guess_type(image.file_name)[0]
        self.response.write(image.blob)


class ImgServe(webapp2.Requesthandler):

    def get(self, resource):

        image = ndb.Key('Images', resource).get()
        self.response.headers[b'Content-Type'] = mimetypes.guess_type(image.file_name)[0]
        self.response.write(image.blob)            

下面是一个静态的表单,用来提交图片:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Image Upload</title>
</head>
<body>
<form action="/file_upload" enctype="multipart/form-data" method="post">
    <div><input type="file" name="file"/></div>
    <div><input type="submit" value="Upload"></div>
</form>
</body>
</html>

处理表单提交的路由:

webapp2.Route(r'/file_upload', handler='fileupload.FileUpload')

图片服务器的路由: <img alt="test" src="/img_serve/test.png" />

webapp2.Route(r'/img_serve/<resource:(.*)>', handler='fileupload.ImgServe'))

撰写回答