将实例和已处理数据发送到render_template是否效率低下?

时间:2015-07-12 07:27:47

标签: python google-app-engine flask

我正在模板中渲染一个实例列表,每个实例都有一个二进制blob图像。要渲染图像,我需要使用base64对它们进行编码。我不确定如何在循环中编码每个图像,下面的代码不起作用。我也不确定是否将对象列表和编码图像列表传递给render_template会增加网络流量。如何正确编码图像列表,这是否有效?

class A:
    number = ndb.IntegerProperty()
    image = ndb.BlobProperty()
@app.route('/show-all')
def show_all():
    all = A.query().order(A.number).fetch()
    encoded_images = [b64encode(image) for all.image in all]  # Doesn't work
    return make_response(render_template("template.html", title="A", objects=all, images=encoded_images))

2 个答案:

答案 0 :(得分:1)

通过向render_template发送多个内容,您不会发送任何“额外数据”,通过网络发送的唯一数据是最终呈现的模板。

构建所有编码图像的列表略微效率低,因为它们将一次存在于内存中。相反,您可以向模型添加属性,以便在渲染时可以在每个实例上使用a.b64_image

class A:
    image = ndb.BlobProperty()

    @property
    def b64_image(self):
        return b64encode(self.image)

然后在模板中,您可以遍历对象列表中的每个项目,并获取每个项目的base64编码图像。

return render_template('objects.html', objects=objects)
{% for item in objects %}
<div>
    <img src="data:;base64,{{ item.b64_image }}"/>
</div>
{% endfor %}

附注:您不必致电make_response,Flask会自动将字符串(从render_template返回)转换为回复。此外,make_responserender_template是Flask的一部分,而不是Flask-Restful。

正如我在my answer to your previous question中所说的那样,将图像作为数据发送是无效的,因为它们被嵌入到每次生成和发送的html中,而不是由客户端缓存的单独文件。更有效的解决方案是单独存储和提供文件,并将文件的路径存储在数据库中。

答案 1 :(得分:0)

从第二个问题开始: 我不确定你的实现,但是你的响应可能只包含某种类型的web页面,因此不会通过Internet发送任何python对象,那么为什么你认为调用具有不同参数的python函数会导致你要向最终用户发送额外的字节吗?

然而,毕竟,你可以立刻解决这两个问题。只需将一个类对象传递给make_response函数,然后里面这个函数(因此问题2解决了)你可以做(​​实际上你的伪代码非常接近):

encoded_images = [b64encode(obj.image) for obj in objects]