Jak konkatenować ciągi w szablonach django?

Chcę połączyć łańcuch w tagu szablonu django jak

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

Tutaj shop_name jest moją zmienną i chcę połączyć to z resztą ścieżki.
Załóżmy, że mam shop_name=example.com

And I want result to extend shop/example.com/base.html

Author: JMax, 2010-12-08

10 answers

Użyj z:

{% with "shop/"|add:shop_name|add:"/base.html" as template %}
{% include template %}
{% endwith %}
 327
Author: Steven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-24 07:20:21

Nie używaj add dla ciągów znaków, powinieneś zdefiniować niestandardowy znacznik w taki sposób:

Utwórz plik: <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)

A następnie użyj go tak, jak mówi @ Steven

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

Powód unikania add

Zgodnie z docs

Ten filtr najpierw spróbuje zmusić obie wartości do liczby całkowitej... Łańcuchy, które mogą być wymuszone do liczb całkowitych, będą sumowane, nie będą konkatenowane...

Jeśli obie zmienne zdarza się, że są liczbami całkowitymi, wynik byłby nieoczekiwany.

 78
Author: user,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-21 06:28:46

Zmieniłem hierarchię folderów

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

I wtedy poniżej będzie działać.

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

Teraz jest w stanie rozszerzyć bazę.strona html.

 10
Author: Ahsan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-10 11:47:29

From the docs:

Ten znacznik może być używany na dwa sposoby:

  • {% extends "base.html" %} (z cudzysłowami) używa dosłownej wartości " base.html " jako nazwa nadrzędnego szablonu do rozszerzenia.
  • {% extends variable %} używa wartości zmiennej. Jeśli zmienna przetworzy łańcuch znaków, Django użyje tego łańcucha jako nazwy nadrzędnego szablonu. Jeśli zmienna przetworzy się do obiektu szablonu, Django użyje tego obiektu jako szablonu nadrzędnego.

Więc wygląda na to, że nie można użyć filtra do manipulować argumentem. W widoku wywołania musisz utworzyć instancję szablonu przodka lub utworzyć zmienną łańcuchową z prawidłową ścieżką i przekazać ją wraz z kontekstem.

 2
Author: Paulo Scardine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-03 19:55:31

Spójrz na add filtr .

Edit: możesz łączyć filtry, więc możesz to zrobić "shop/"|add:shop_name|add:"/base.html". Ale to nie zadziała, ponieważ to do tagu szablonu należy ocena filtrów w argumentach, a extends nie.

Chyba nie da się tego zrobić w szablonach.

 2
Author: Daniel Hepper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-10 13:10:17

Odpowiedź @ error jest zasadniczo słuszna, powinieneś używać do tego znacznika szablonu. Jednak wolę nieco bardziej ogólny znacznik szablonu, którego mogę użyć do wykonywania dowolnych operacji podobnych do tego:

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 ''

I wtedy możesz użyć go w ten sposób w szablonie:

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

Jak wspomniano w komentarzu, ten znacznik szablonu jest szczególnie przydatny dla informacji, które są powtarzalne w całym szablonie, ale wymagają logiki i innych rzeczy, które będą zawierały Twoje szablony, lub w przypadkach, w których chcesz ponownie wykorzystać dane przekazywane między szablonami poprzez bloki:

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

A następnie:

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

Kredyt dla tagu captureas jest należny tutaj: https://www.djangosnippets.org/snippets/545/

 1
Author: K3TH3R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-22 03:15:02

Praca z tagiem {% with %} była dość kłopotliwa. Zamiast tego utworzyłem następujący tag szablonu, który powinien działać na ciągach znaków i liczbach całkowitych.

from django import template

register = template.Library()


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

Następnie załaduj znacznik szablonu w szablonie u góry, używając następującego wzoru:

{% load concat_string %}

Możesz użyć go w następujący sposób:

<a href="{{ SOME_DETAIL_URL|concat_string:object.pk }}" target="_blank">123</a>
Osobiście uważam, że jest to dużo czystsze do pracy.
 1
Author: Bono,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 12:05:44

Zobacz łączenie łańcuchów w szablonach Django :

  1. Dla wcześniejszych wersji Django:

    {{ "Mary miała trochę"|stringformat:"s Baranek." }}

"Mary miała małą owieczkę."

  1. Else:

    {{"Marysia miała trochę" / dodaj: "Baranek." }}

"Mary miała małą owieczkę."

 1
Author: bing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-05 03:08:45

Nie możesz manipulować zmiennymi w szablonach django. Masz dwie opcje: napisz własny znacznik szablonu lub zrób to w widoku,

 0
Author: damir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-08 10:05:22

extends nie ma na to możliwości. Albo umieść całą ścieżkę szablonu w zmiennej kontekstowej i użyj jej, albo skopiuj znacznik exist template i odpowiednio go zmodyfikuj.

 0
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-08 11:20:58