In Django, is there an easy way to render a text field as a template, in a template?

随声附和 提交于 2019-12-29 05:00:07

问题


Can you think of an easy way to evaluate a text field as a template during the template rendering.

I know how to do it in a view but I'm looking for a template Filter or a Tag ?

Something like:

{{ object.textfield|evaluate}} or {% evaluate object.textfield %}

with object.textfield containing something like:

a text with a {% TemplateTag %}.

In which TemplateTag will be evaluated, thanks to the evaluate filter.


回答1:


Here is a first Tag implementation to solve my question:

from django import template

register = template.Library()

@register.tag(name="evaluate")
def do_evaluate(parser, token):
    """
    tag usage {% evaluate object.textfield %}
    """
    try:
        tag_name, variable = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
    return EvaluateNode(variable)

class EvaluateNode(template.Node):
    def __init__(self, variable):
        self.variable = template.Variable(variable)

    def render(self, context):
        try:
            content = self.variable.resolve(context)
            t = template.Template(content)
            return t.render(context)
        except template.VariableDoesNotExist, template.TemplateSyntaxError:
            return 'Error rendering', self.variable



回答2:


It's going to involve regular expressions. Something I'm not so good at, I've written an example but you (or someone else here) will (I guarantee) have a more efficient way of doing this. But this is just an example:

from django.template import Library, Node, TemplateSyntaxError
from django.template import Template, Context

register = Library()

class TemplateEvalNode(Node):
    def __init__(self, value):
        self.value = Variable(value)

    def render(self, context):
        value = self.value.resolve(context)
        regex = re.compile('{% \w+ %}')
        # Grab the template tag (eg. {% TemplateTag %})
        unevaluated_var = regex.search(value)

        if unevaluated_var == None:
            return value

        # Create a template containing only the template tag
        t = Template(unevaluated_var)
        # Evaluate that template (with context)
        return_var = t.render(Context(context))

        # Return the original value with the template tag replaced with
        # its actual value
        return value.replace(unevaluated_var, return_var)

def template_eval(parser, token):
    bits = token.contents.split()
    if len(bits) != 2:
        raise TemplateSyntaxError, "template_eval takes exactly one argument"
    return TemplateEvalNode(bits[1])

template_eval = register.tag(template_eval)

I haven't tested this yet, so it may not work straight off, but in theory you can run:

{% template_eval object.textfield %}

And it would return:

a text with a VALUE_OF_TEMPLATETAG.

Expect an update to this as I'm going to test it now and attempt to fix any problems, my battery is about to die so I'm posting this now untested.

Also expect a much more clever solution from someone who is better at Python than I am :p.

EDIT: OK, I was too slow, you beat me!



来源:https://stackoverflow.com/questions/1278042/in-django-is-there-an-easy-way-to-render-a-text-field-as-a-template-in-a-templ

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!