如何正确使用 Images Python API 显示带用户评论的头像?

0 投票
1 回答
1013 浏览
提问于 2025-04-16 08:00

这是我之前提问的后续问题,关于如何从Blobstore显示图片。我正在尝试上传并显示一张作为头像的图片,参考了这个示例应用。

这是我正在使用的代码:

upload.py 文件中,我有:

from google.appengine.api import images

class Upload(webapp.RequestHandler):
    def get(self):
    self.response.out.write("""
          <form action="/avatar-save" enctype="multipart/form-data" method="post">                
            <div><label>Avatar:</label></div>
            <div><input type="file" name="img"/></div>
          </form>
        </body>
      </html>""")

class AvatarSave(webapp.RequestHandler):
    def post(self):
        avatar = images.resize(self.request.get("img"), 32, 32)
        greeting.avatar = db.Blob(avatar)
        greeting.put()
        self.redirect('/')


application = webapp.WSGIApplication(
                                 [('/upload', Upload),
                                  ('/avatar-save', AvatarSave),
                                  ],
                                 debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

我第一个问题是:我怎么检查 AvatarSave 是否真的把图片保存到了数据存储中?

我尝试在 hw.py 中显示这张图片:

class MainPage(webapp.RequestHandler):
    def get(self):
    siteUser = users.get_current_user()
    greeting = None        
    if siteUser:
        greeting = ("Welcome, %s! (<a href=\"%s\">sign out</a>)" %
                    (siteUser.nickname(), users.create_logout_url("/")))
    else:
        greeting = ("<a href=\"%s\">Sign in or register</a>" %
                    users.create_login_url("/"))

    self.response.out.write(greeting)           

    query = User.all()
    query.order("-userScore")
    results = query.fetch(10)
    self.response.out.write("""<html><head><style>
                               body {font-size: small;
                                     font-family: Verdana, Helvetica, sans-serif;
                                    }</style>
                                    </head><body><ol>""")
    for result in results:
        self.response.out.write("<li>")
        self.response.out.write("<b>%s</b> %s " % (result.userName, result.userLatestComment))
        self.response.out.write("<div><img src='img?img_id=%s'></img>" % result.key())
        self.response.out.write("</li>")
    self.response.out.write("</ol></body></html>")


class Image (webapp.RequestHandler):
    def get(self):
        greeting = db.get(self.request.get("img_id"))
        if greeting.avatar:
            self.response.headers['Content-Type'] = "image/png"
            self.response.out.write(greeting.avatar)
    else:
        self.response.out.write("No image")


application = webapp.WSGIApplication(
                                 [('/', MainPage),
                                  ('/img', Image),
                                  ],
                                 debug=True)

但是我看到的只是每行显示的破损图片链接图标。(我一共显示了8行。)

在日志中我看到这个:

INFO     2010-12-04 01:03:57,641 dev_appserver.py:3283] "GET / HTTP/1.1" 200 -
INFO     2010-12-04 01:03:57,703 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGBMM HTTP/1.1" 200 -
INFO     2010-12-04 01:03:57,756 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGBUM HTTP/1.1" 200 -
INFO     2010-12-04 01:03:58,734 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGBIM HTTP/1.1" 200 -
INFO     2010-12-04 01:03:58,812 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGFkM HTTP/1.1" 200 -
INFO     2010-12-04 01:03:58,878 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGFsM HTTP/1.1" 200 -
INFO     2010-12-04 01:03:58,934 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGFoM HTTP/1.1" 200 -
INFO     2010-12-04 01:03:58,986 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGGkM HTTP/1.1" 200 -
INFO     2010-12-04 01:03:59,040 dev_appserver.py:3283] "GET /img?img_id=ag1oZWxsby0xLXdvcmxkcgoLEgRVc2VyGGwM HTTP/1.1" 200 -
INFO     2010-12-04 01:04:00,102 dev_appserver.py:3283] "GET /favicon.ico HTTP/1.1" 200 -

据我了解,有些图片是从数据存储中获取的;但我只上传了一张图片(或者我以为我只上传了一张),但根据日志显示每张图片的ID都是不同的。

有人能帮我理解这里发生了什么吗?以及如何解决这个问题?非常感谢你的帮助。


更新

根据 Ben 的回答,我更新了代码如下:

这是我正在使用的模型:

class User(db.Model):
    userEmail = db.StringProperty()
    ....
    avatar = db.BlobProperty()

这是新的 AvatarSave

class AvatarSave(webapp.RequestHandler):
    def post(self):
        q = User.all()
        q.filter("userEmail =", "az@example.com")
        qTable = q.fetch(1)
        if qTable:
            for row in qTable:
            avatar = images.resize(self.request.get("img"), 32, 32)
            row.avatar = db.Blob(avatar)
            db.put(qTable)
        else:
            self.response.out.write("user not found")

        self.redirect('/')

我相信这现在更新了与 userEmail "az@example.com" 关联的用户的头像。这是正确的吗?

我也更新了 hw.py 只显示这个用户:

query = User.all()
    query.filter("userEmail =", "az@example.com")
    results = query.fetch(1)
    self.response.out.write("""<html><head><style>
                               body {font-size: small;
                                     font-family: Verdana, Helvetica, sans-serif;
                                    }</style>
                                    </head><body><ol>""")
    for result in results:
        self.response.out.write("<li>")
        self.response.out.write("<b>%s</b> %s " % (result.userName, result.userLatestComment))
        self.response.out.write("<div><img src='img?img_id=%s'></img>" % result.key())
        self.response.out.write("</li>")
    self.response.out.write("</ol></body></html>")

但仍然有问题,因为我看到的不是图片,而是 "None",而且图片链接是破损的。

此外,当我查看 Datastore Viewer 时,我没有看到 "avatar" 列。但我看到某个 blob 在某个时刻被更新过:

Entity Kind: __BlobUploadSession__
Key: ag10ZWxs....
ID: 125
Key Name:
creation: 1291388993.27
state: init
success_path: /upload

我不确定这里发生了什么以及如何解决这个问题。任何建议都欢迎。

1 个回答

1

在日志中,你看到不同的图片ID是因为你从数据存储中请求了最多10个用户对象,而数据存储的查询是查找所有用户,不管他们是否有存储的图片(可能在测试过程中你创建了8个用户对象)。

至于为什么头像没有保存:

class AvatarSave(webapp.RequestHandler):
    def post(self):
        avatar = images.resize(self.request.get("img"), 32, 32)
        greeting.avatar = db.Blob(avatar)

除非你的代码示例中缺少某些部分,否则“greeting”变量在这里没有被设置。你需要先创建一个新的问候(也就是创建一个新的实例,使用你所用的模型),或者加载合适的问候,然后把头像设置上去,最后调用greeting.put()来保存。

更新

如果你的代码缩进是这样的:

    qTable = q.fetch(1)
    if qTable:
        for row in qTable:
        avatar = images.resize(self.request.get("img"), 32, 32)
        row.avatar = db.Blob(avatar)
        db.put(qTable)

那是行不通的。你可能想要的是:

    qTable = q.fetch(1)
    if qTable:
        for row in qTable:
            avatar = images.resize(self.request.get("img"), 32, 32)
            row.avatar = db.Blob(avatar)
        db.put(qTable)

但是因为你这里只处理一个对象,所以用fetch(1)的方式会比较复杂,不如直接这样做:

    currentUser = q.get()
    if currentUser is not None:
        avatar = images.resize(self.request.get("img"), 32, 32)
        currentUser.avatar = db.Blob(avatar)
        currentUser.put()

撰写回答