Как запустить код Django, сохраненный внутри экземпляров модели?

Я использую пользовательскую модель Django (v1.5.5) Widget, которая содержит HTML-код (с использованием TextField) для размещения в определенных местах на разных страницах и позволяет сотрудникам легко изменять содержимое через административную часть Django.

Этот подход отлично работает с кодом HTML, CSS и Javascript. Используя следующий синтаксис в шаблонах:

{{ widget.content|safe }}

Тем не менее, я также хотел бы иметь возможность поместить в него код Django (используя теги шаблонов, методы вызова...), но этот код Django НЕ выполняется, а вместо этого он напрямую печатается, как если бы это был обычный текст.

Есть ли способ выполнить код Django с использованием фильтра safe? Или я пропустил еще один фильтр? Возможно, мне придется использовать собственный фильтр или тег шаблона... Есть идеи?

Спасибо!


person Caumons    schedule 08.01.2014    source источник


Ответы (2)


По умолчанию в Django нет такого тега/фильтра шаблона. Я использую это в одном из своих проектов:

class IncludeString(ttag.Tag):
    template_src = ttag.Arg()

    def render(self, context):
        data = self.resolve(context)
        try:
            t = loader.get_template_from_string(data['template_src'])
        except Exception, e:
            return u"error rendering template: %s" % unicode(e)
        return t.render(context)

    class Meta:
        name = "include_string"

register.tag(IncludeString)

И используйте его как {% include_string variable_name_with_template_content %}. В этой реализации используется django-ttag, но я думаю, что что-то вроде следующего также должно работать (не проверено):

@register.simple_tag(takes_context=True)
def include_string(context, template_src):
    try:
        t = loader.get_template_from_string(template_src)
        return t.render(context)
    except Exception, e:
        return u"error rendering template: %s" % unicode(e)
person sk1p    schedule 09.01.2014
comment
Большое спасибо за ответ sk1p! Я смог найти действительно KISS-решение на основе того, что вы объяснили. +1 :) - person Caumons; 09.01.2014

Основываясь на ответе @ sk1p, я создал Django simple_tag, который принимает строку HTML (которая может содержать «код Django») и context (что здесь абсолютно необходимо). Затем я просто визуализирую его и возвращаюсь. Вот и все!

Я создал файл с именем smart_html.py, который содержит:

from django import template
from django.template import Template


register = template.Library()


@register.simple_tag(takes_context=True)
def render_html(context, html):
    return Template(html).render(context)

Затем из шаблонов мне просто нужно сделать:

{% load smart_html %}
{% render_html widget.content %}
person Caumons    schedule 09.01.2014