传递给模板标签时如何使用上下文变量

时间:2020-02-04 11:38:05

标签: django django-templates

我使用以下模板标记来允许在模板内设置自定义变量:

class SetVarNode(template.Node):
     def __init__(self, new_val, var_name):
        self.new_val = new_val
        self.var_name = var_name

    def render(self, context):
        context[self.var_name] = self.new_val
        return ''

@register.tag
def setvar(parser, token):    
    # This version uses a regular expression to parse tag contents.
    try:
        # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires arguments" % token.contents.split()[0]
        )
    m = re.search(r'(.*?) as (\w+)', arg)
    if not m:
        raise template.TemplateSyntaxError(
            "%r tag had invalid arguments" % tag_name
        )
    new_val, var_name = m.groups()
    if not (new_val[0] == new_val[-1] and new_val[0] in ('"', "'")):
        raise template.TemplateSyntaxError(
            "%r tag's argument should be in quotes" % tag_name
        )
    return SetVarNode(new_val[1:-1], var_name)

这使我可以一次在模板中使用一个变量:{% setvar "a string" as new_template_var %}

如何修改它以允许我的变量与现有的上下文变量连接?

例如我想将context['var1']传递给setvar作为

{% setvar "a string {{ var1 }}" as new_template_var %}

但是{{ var1 }}作为字符串而不是变量值本身包含。

2 个答案:

答案 0 :(得分:0)

简单的解决方案:用过滤器连接您的垃圾字符串和变量,即:

{% setvar "a string"|add:var1 as new_template_var %}

但是您必须在节点中correctly handle templates VariableFilterExpression才能将变量名称解析为其当前上下文值。

话虽如此,这确实是不必要的(除非您有更多要求或只是出于学习目的而这样做):

最后,如果您只需要对自定义上下文更新模板标签使用简单的语法,请考虑使用simple_tag()快捷方式,该快捷方式支持将标签结果分配给模板变量。

https://docs.djangoproject.com/en/3.0/howto/custom-template-tags/#setting-a-variable-in-the-context

答案 1 :(得分:-1)

在您的SetVarNode.render(..)中,您必须将其启动为模板,并使用context进行渲染。

未经测试:

class SetVarNode(template.Node):
    def __init__(self, new_val, var_name):
        self.new_val = new_val
        self.var_name = var_name

    def render(self, context):
        t = Template(self.new_val)
        value = t.render(context)
        context[self.var_name] = value
        return ''