【问题标题】:How to use a context variable when passing to a template tag传递给模板标签时如何使用上下文变量
【发布时间】:2020-02-04 11:38:05
【问题描述】:

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

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 }} 是作为字符串包含的,而不是变量值本身。

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

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

    {% 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)

    【讨论】:

      【解决方案2】:

      在您的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 ''
      

      【讨论】:

      • 谢谢,很遗憾这会导致'module' object is not callable
      • 正确的解决方案是在 Templetag 调用中使用模板过滤器。
      猜你喜欢
      • 1970-01-01
      • 2020-04-24
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      • 2014-03-10
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多