我想在Django模板标签中连接一个字符串,比如:

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

这里shop_name是我的变量,我想将它与rest of path连接起来。

假设我有shop_name=example.com,我想要结果扩展shop/example.com/base.html。


当前回答

您不需要编写自定义标记。只需要对相邻的变量求值。

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

其他回答

@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/

我已经更改了文件夹层次结构

/shop_name/shop/base.html

下面也可以。

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

现在它能够扩展base.html页面。

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

@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 'shop/%s/base.html' shop_name as template %}
{% include template %}

好的部分是format_string可以在模板中的任何类型的字符串格式化中重用

我发现使用{% 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>

我个人觉得这样工作起来更简洁。

不要对字符串使用add,你应该这样定义一个自定义标签:

创建一个文件:<appname>\templatetags\<appname>_extra .py

from django import template

register = template.Library()

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

然后像@Steven说的那样使用它

{% load <appname>_extras %}

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

避免添加的原因:

根据文件

这个过滤器将首先尝试将两个值强制转换为整数… 可以强制转换为整数的字符串将被求和,而不是连接…

如果两个变量都是整数,结果就会出乎意料。