Как правильно использовать Images Python API для отображения аватара с комментариями пользователей? - PullRequest
0 голосов
/ 04 декабря 2010

Это дополнительный вопрос к моему предыдущему вопросу . Я пытаюсь загрузить и отобразить изображение в виде аватара, следуя примеру приложения здесь .

Это код, который я использую:

В 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 -

Насколько я понимаю, некоторые изображения извлекаются из хранилища данных; но я загрузил только 1 изображение (или я думал, что сделал), но в соответствии с журналами идентификатор для каждого изображения отличается.

Может кто-нибудь помочь мне понять, что здесь происходит; и как это исправить? Большое спасибо за вашу помощь.


Обновление

В ответ на ответ Бена Я обновил код так:

Это модель, которую я использую:

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". Но я вижу, что какой-то шарик был обновлен в какой-то момент:

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

Не уверен, что здесь происходит и как это исправить. Любое предложение будет приветствоваться.

1 Ответ

1 голос
/ 04 декабря 2010

В журнале вы видите разные идентификаторы изображений, потому что вы запрашиваете до 10 пользовательских объектов из хранилища данных, а запрос хранилища данных ищет пользователей независимо от того, хранится ли у них изображение (возможно, вы сделал 8 пользовательских объектов в процессе тестирования).

Почему аватары не сохраняются:

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

Если в вашем примере отсутствует какой-либо код, переменная "welcome" здесь не установлена. Вы должны сначала создать новое приветствие (создав новый экземпляр той модели, которую он использует) или загрузить соответствующую, затем установить для него аватар, затем приветствие.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()
...