Как мога ефективно да изобразя изображение в Django?

Пиша малко приложение 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)

Смес от горното:

Ще има шаблон по подразбиране.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 е най-добрият по отношение на използваемостта, но смятам, че ще повлияе много на представянето. Някакви съвети?


person XelharK    schedule 07.05.2014    source източник
comment
Е.. Ще оставя някой друг да ви даде конкретни съвети, но един често срещан отговор на въпроса ви е Не се тревожете за производителността, докато не се наложи. Ако харесвате #3 и изглежда, че не изяжда всички налични ресурси, давайте.   -  person Ambroise    schedule 07.05.2014


Отговори (1)


По мое мнение и мисля, че мнозина споделят тази гледна точка с мен, моделът не трябва да носи отговорност за представянето си в HTML, така че наличието на model.image.render_tag ми се струва грешно.

Единствените части в приложението, които знаят как да представят нещо в HTML, трябва да бъдат изгледите и техните шаблони.

Можете да имате помощна функция, която генерира HTML за изображение и да го използвате във вашите изгледи, можете също да имате simple_tag, който препраща към тази функция, така че да можете да я използвате във вашите шаблони.

Ако ефективността на извикването му във вашите шаблони е проблем, обмислете използването на машина за шаблони с по-добра производителност - можете да се обърнете към този SO отговор за бенчмарк на машини за шаблони - или можете да извикате тази помощна функция във вашия изглед и да прехвърлите резултата(ите) към вашия шаблон чрез контекста.

Актуализация

Ще демонстрирам какво имах предвид по-горе с пример.

# 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>
person mpcabd    schedule 07.05.2014
comment
Не говоря за МОЕТО представяне, но тъй като бих искал да разпространявам това приложение, бих искал да няма удар по отношение на представянето. Това обаче не е въпросът. Не съм сигурен, че разбирам какво имате предвид с Можете да имате помощна функция, която генерира HTML за изображение и да го използвате във вашите изгледи, можете също да имате simple_tag, който препраща към тази функция, така че да можете използвайте го във вашите шаблони. Бихте ли разяснили малко това? - person XelharK; 07.05.2014
comment
Добре, това изглежда като това, което имах предвид, когато говорех за моята опция №2. Може ли това да стане само с шаблона? Фактът, че изобразявам друг шаблон (и евентуално много повече), влияе ли върху представянето? - person XelharK; 07.05.2014
comment
Да, почти същото е, но съм използвал simple_tag вместо filter, защото вярвам, че е много по-динамичен. И както можете да видите в SO отговора, към който съм се свързал, производителността наистина има значение и зависи от машината за шаблони, но шаблонът на Django от малки до средни по размер приложения все още би бил перфектен избор. - person mpcabd; 08.05.2014