如何在Django中高效渲染图像?

时间:2014-05-07 10:56:38

标签: python django django-templates

我正在编写一个小型django应用程序来处理图像。 我想尽可能干这个,所以这是我的目标:

用户上传文件,并输入一些字段,如标题,替代文字,标题等。

在模板上,我希望能够做到这样的事情:

model.image.render_tag

会输出如下内容:

<img src='path/image.jpg' title='title' alt_text='alt_text..' />

问题是该行应该在模板上,因此如果开发人员需要添加一些内容或删除其他内容,他们只需编辑模板,渲染将在所有渲染图像中发生变化。

还可以添加第二个模板并渲染该模板。

现在,有几种方法可以实现这一目标:

1)

只需包含一个呈现命名空间变量的模板,并强制开发人员每次“更改”图像变量名称,模板将类似于:

<img src="{{ namespaced_image.raw.path }}" alt_text="{{ namespaced_image.alt_text }}"... />

在这种情况下,开发人员应该在包含路径之前将映像重命名为其命名空间版本。

类似的东西:

{% with namespaced_image=image %}
    {% include images/template.html %}
{% end with %}

2)

根据用户可在设置中编辑的原始字符串添加模板标记以呈现图像,例如

settings.py

namespaced_image_tag="<img src={path} ... />"

我的模板标签会像

那样
@register
def rendered_tag(image)
    return namespaced_image_tag.format(path=image.raw.path, ...)

因此,开发人员只需添加自定义标记文件并使用

即可
{% load images_filters %}

{{ image|rendered_tag }}

3)

以上的混合物:

将会有一个包含标记的默认template.html,以及一个模板标记,它通过为模板提供命名空间图像作为上下文来呈现模板。

@register
def rendered_tag(image, template="default_template.html")
    return render_template(template, namespaced_image=image)

所以开发人员可以做类似

的事情
{% load images_filters %}
{{ image|rendered_tag }}
{{ image|rendered_tag:"custom_template_name" }}

我不知道,每个请求如何渲染多个模板会影响性能。

另外,我不太喜欢选项#1,因为它不可用和可读。

选项#2很糟糕,因为我不能使用不同的“模板”,也不能扩展其他模板。我也不太喜欢模板标签,特别是因为用户被迫在每个使用过的模板中导入文件。

选项#3在可用性方面是最好的,但我觉得它会影响很多表演。有什么提示吗?

1 个答案:

答案 0 :(得分:1)

在我看来,我认为很多人与我分享这个观点,一个模型不应该对它在HTML中的表示负责,所以让model.image.render_tag对我来说似乎不对。

应用中唯一知道如何用HTML表示任何内容的部分应该是视图及其模板。

您可以使用帮助函数生成图像的HTML,并在视图中使用它,您也可以使用simple_tag引用该函数,以便在模板中使用它。 / p>

如果在模板中调用它的性能是一个问题,请考虑使用更好的性能模板引擎 - 您可以参考此SO answer获取模板引擎的基准 - 或者您可以调用该帮助函数您的视图并通过上下文将结果传递给您的模板。

更新

我将通过一个例子展示我的意思。

# inside html_utils.py

def image_to_html(image):
    return '<img src="%(path)s" title="%(title)s" alt="%(alt)s" />' % {
        'path': image.raw.path,
        'title': image.title,
        'alt': image.alt_text
    }

# inside html_template_utils.py

import html_utils
from django import template

register = template.Library()

@register.simple_tag
def image_tag(image):
    return html_utils.image_to_html(image)

{# inside images_template.html #}

{% load html_template_utils %}

<div class="images-container">
{% for image in images %}
    {% image_tag image %}
{% endfor %}
</div>

上面的代码使用我们创建的image_to_html image_tag模板中的simple_tag辅助函数。另一种可能的方法是在视图中调用image_to_html并将结果传递给模板:

# inside views.py

import html_utils

def view_images(request):
    # ...

    images_html = [html_utils.image_to_html(image) for image in images]

    # ...

    return render_to_response('images_template.html', {
        'images_html': images_html
    }, context_instance=RequestContext(request))

{# inside images_template.html #}

<div class="images-container">
{% for image_html in images_html %}
    {{ image_html }}
{% endfor %}
</div>