如何在django模板中连接字符串?

时间:2010-12-08 09:58:14

标签: django string templates concatenation

我想在django模板标签中连接字符串,如

{% extend shop/shop_name/base.html %}

这里shop_name是我的变量,我想将其与路径的其余部分连接起来 假设我有shop_name=example.com

我希望结果扩展shop/example.com/base.html

14 个答案:

答案 0 :(得分:355)

使用:

{% with "shop/"|add:shop_name|add:"/base.html" as template %}
{% include template %}
{% endwith %}

答案 1 :(得分:92)

不要将add用于字符串,您应该定义一个这样的自定义标记:

创建文件:<appname>\templatetags\<appname>_extras.py

from django import template

register = template.Library()

@register.filter
def addstr(arg1, arg2):
    """concatenate arg1 & arg2"""
    return str(arg1) + str(arg2)

然后将其用作@Steven说

{% with "shop/"|addstr:shop_name|addstr:"/base.html" as template %}
    {% include template %}
{% endwith %}

避免add

的原因

根据docs

  

此过滤器首先尝试将两个值强制转换为整数...   可以强制转换为整数的字符串将被加总,不连接 ......

如果两个变量都是整数,结果将是意外的。

答案 2 :(得分:10)

我更改了文件夹层次结构

  

/shop/shop_name/base.html /shop_name/shop/base.html

然后下面就可以了。

{% extends shop_name|add:"/shop/base.html"%} 

现在它可以扩展base.html页面。

答案 3 :(得分:3)

查看add filter

编辑:您可以链接过滤器,因此您可以执行"shop/"|add:shop_name|add:"/base.html"。但这不起作用,因为它取决于模板标签来评估参数中的过滤器,而扩展则不是。

我猜你不能在模板中做到这一点。

答案 4 :(得分:2)

来自文档:

此标记可以两种方式使用:

  • {% extends "base.html" %}(带引号)使用文字值“base.html”作为要扩展的父模板的名称。
  • {% extends variable %}使用变量的值。如果变量求值为字符串,Django将使用该字符串作为父模板的名称。如果变量求值为Template对象,Django将使用该对象作为父模板。

所以好像你不能使用过滤器来操纵参数。在调用视图中,您必须实例化祖先模板或使用正确的路径创建字符串变量,并将其与上下文一起传递。

答案 5 :(得分:2)

请参阅Concatenating Strings in Django Templates

  1. 对于早期版本的Django:

    {{ "Mary had a little"|stringformat:"s lamb." }}

  2.   “玛丽有一只小羊羔。”

    1. 否则:

      {{ "Mary had a little"|add:" lamb." }}

    2.   “玛丽有一只小羊羔。”

答案 6 :(得分:1)

@ error的答案基本上是正确的,你应该为此使用模板标签。但是,我更喜欢一个稍微更通用的模板标签,我可以使用它来执行与此类似的任何操作:

from django import template
register = template.Library()


@register.tag(name='captureas')
def do_captureas(parser, token):
    """
    Capture content for re-use throughout a template.
    particularly handy for use within social meta fields 
    that are virtually identical. 
    """
    try:
        tag_name, args = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError("'captureas' node requires a variable name.")
    nodelist = parser.parse(('endcaptureas',))
    parser.delete_first_token()
    return CaptureasNode(nodelist, args)


class CaptureasNode(template.Node):
    def __init__(self, nodelist, varname):
        self.nodelist = nodelist
        self.varname = varname

    def render(self, context):
        output = self.nodelist.render(context)
        context[self.varname] = output
        return ''

然后您可以在模板中使用它:

{% captureas template %}shop/{{ shop_name }}/base.html{% endcaptureas %}
{% include template %}

正如评论所提到的,这个模板标签对于整个模板中可重复的信息特别有用,但需要逻辑和其他东西来填补你的模板,或者在你希望重新使用模板之间传递的数据的情况下块:

{% captureas meta_title %}{% spaceless %}{% block meta_title %}
    {% if self.title %}{{ self.title }}{% endif %}
    {% endblock %}{% endspaceless %} - DEFAULT WEBSITE NAME
{% endcaptureas %}

然后:

<title>{{ meta_title }}</title>
<meta property="og:title" content="{{ meta_title }}" />
<meta itemprop="name" content="{{ meta_title }}">
<meta name="twitter:title" content="{{ meta_title }}">

对于captureas标记的信用是由于:https://www.djangosnippets.org/snippets/545/

答案 7 :(得分:1)

我发现使用{% with %}代码非常麻烦。相反,我创建了以下模板标记,它应该适用于字符串和整数。

from django import template

register = template.Library()


@register.filter
def concat_string(value_1, value_2):
    return str(value_1) + str(value_2)

然后使用以下内容在顶部的模板中加载模板标记:

{% load concat_string %}

然后您可以通过以下方式使用它:

<a href="{{ SOME_DETAIL_URL|concat_string:object.pk }}" target="_blank">123</a>

我个人认为这可以更加清洁。

答案 8 :(得分:1)

您不需要编写自定义标签。只需评估彼此相邻的变量。

"{{ shop name }}{{ other_path_var}}"

答案 9 :(得分:0)

你不能在django模板中进行变量操作。 您有两个选项,可以编写自己的模板标记,也可以在视图中执行此操作,

答案 10 :(得分:0)

extends没有这方面的便利。将整个模板路径放在上下文变量中并使用它,或者复制现有模板标记并进行适当修改。

答案 11 :(得分:0)

以及多个串联:

from django import template
register = template.Library()


@register.simple_tag
def concat_all(*args):
    """concatenate all args"""
    return ''.join(map(str, args))

在模板中:

{% concat_all 'x' 'y' another_var as string_result %}
concatenated string: {{ string_result }}

答案 12 :(得分:0)

在我的项目中,我这样做的是:

innerHTML

例如,您想要连接的字符串和args可以来自视图。

在模板中并使用您的案例:

@register.simple_tag()
def format_string(string: str, *args: str) -> str:
    """
    Adds [args] values to [string]
    String format [string]: "Drew %s dad's %s dead."
    Function call in template: {% format_string string "Dodd's" "dog's" %}
    Result: "Drew Dodd's dad's dog's dead."
    """
    return string % args

令人高兴的是,format_string可以在模板中的任何类型的字符串格式中重复使用

答案 13 :(得分:0)

这个怎么样!我们有 first_namelast_name,我们希望它们显示空格 " " 分隔。

{% with first_name|add:' '|add:last_name as name %}
    <h1>{{ name }}</h1>
{% endwith %}

我们实际上在做的是:first_name + ' ' + last_name