web-dev-qa-db-ja.com

Djangoテンプレートの文字列を連結する方法は?

次のように、Djangoテンプレートタグ内の文字列を連結します。

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

ここでshop_nameは私の変数であり、これを残りのパスと連結したいと思います。

shop_name=example.comがあり、結果にshop/example.com/base.htmlを拡張したいとします。

178
Ahsan

で使用:

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

文字列に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

このフィルターは、first両方の値を整数に変換しようとします...整数に変換できる文字列は合計されます連結されていない...

両方の変数が整数である場合、予期しない結果になります。

96
user

フォルダ階層を変更しました

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

そして、以下が動作します。

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

Base.htmlページを拡張できるようになりました。

11
Ahsan

add filter をご覧ください。

編集:フィルターを連鎖できるので、"shop/"|add:shop_name|add:"/base.html"を実行できます。ただし、引数内のフィルターを評価するのはテンプレートタグ次第であり、拡張機能は機能しないため、機能しません。

テンプレート内でこれを行うことはできないと思います。

3
Daniel Hepper

Djangoテンプレートの文字列の連結 を参照してください。

  1. Djangoの以前のバージョンの場合:

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

「メアリーには小さな子羊がいた。」

  1. その他:

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

「メアリーには小さな子羊がいた。」

3
bing

ドキュメントから:

このタグは2つの方法で使用できます。

  • {% extends "base.html" %}(引用符付き)は、リテラル値 "base.html"を拡張する親テンプレートの名前として使用します。
  • {% extends variable %}は、変数の値を使用します。変数が文字列に評価される場合、Djangoはその文字列を親テンプレートの名前として使用します。変数がTemplateオブジェクトに評価される場合、Djangoはそのオブジェクトを親テンプレートとして使用します。

フィルターを使用して引数を操作することはできないようです。呼び出しビューでは、祖先テンプレートをインスタンス化するか、正しいパスで文字列変数を作成してコンテキストで渡す必要があります。

2
Paulo Scardine

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

1
K3TH3R

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

私は個人的に、これが動作するようにはるかにきれいであることがわかりました。

1
Bono

extendsにはこの機能はありません。テンプレートパス全体をコンテキスト変数に入れて使用するか、既存のテンプレートタグをコピーして適切に変更します。

Djangoテンプレートで変数操作を行うことはできません。 2つのオプションがあります。独自のテンプレートタグを記述するか、ビューでこれを行います。

0
damir