Pergunta

I am trying to serve images dynamically with Python on Google App Engine, asking the user to enter a name, a comment and potentially load an image.

I created the following class:

class Comment(db.Model):
    name = db.StringProperty(required=True)
    comment = db.TextProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    image = db.BlobProperty()

I then wrote the post method:

def post(self):
    name = self.request.get("name")
    comment = self.request.get("comment")
    image = self.request.get("img")
    if name and comment:
        if image:
            c = Comment(name=name, comment=comment)
            image = images.resize(self.request.get('img'), 32, 32)
            c.image = db.Blob(image)
            c.put()
            time.sleep(0.5)
            self.redirect("/")

The get method would be represented as follows:

def render_front(self, name="", comment="", image="", error=""):
    comments = Comment.all().order('-created')
    self.render("front.html", name=name, comment=comment, image=image, error=error, comments=comments)

def get(self):
    self.render_front()

I finally serve this in my HTML template:

{% for e in comments %}
    <div class="comment">
        <div class="comment-name">
            {{e.name}}
        </div>
        <pre class="comment-content">
            {{e.comment}}
            <br>
            on {{e.created}}
        </pre>
        <div class="comment-image">
            {{e.image}}
        </div>
    </div>
{% endfor %}

I've got the following error:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)

I have the PIL library installed by the way. Any ideas on how I could solve this?

Thanks in advance for your help.

Foi útil?

Solução

You have a few options.
Note that this is pesudo code, it will definitely need fixing.

The simpler one is to add a link to the image in your html

 <a href="./image/?key={{e.key()}}">

The browser will create a new http request for the image, then you create a handler to serve the image (and only the image) to this request.

def get(self):
    c = Comment.get(self.request.get("key"))
    self.response.headers['Content-Type'] = "image/jpeg"
    self.response.out.write(c.image)

Second solution is to encapsulate the image in the html flow like

<img src="data:image/gif;base64,RAAA...more data.....">

You'll need to base64 encode the data but that's standard in python.

Third solution would be to store the image in blobstore and add a link to it in the html page (as for solution 1). This has the advantage that serving the image will not load your app engine server and will use Google static data server so Google will try to get it cached at various levels if possible.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top