Como concatenar strings nos templates do django?

Eu quero concatenar string na tag de template do django como

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

Aqui shop_name é minha variável e quero concatenar isso com o restante do caminho.
Suponha que eu tenha shop_name=example.com

E quero que o resultado amplie shop/example.com/base.html

Usar com:

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

Não use add for strings, você deve definir uma tag customizada como esta:

Crie um arquivo: \templatetags\_extras.py

 from django import template register = template.Library() @register.filter def addstr(arg1, arg2): """concatenate arg1 & arg2""" return str(arg1) + str(arg2) 

e depois usá-lo como @Steven diz

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

Razão para evitar add

De acordo com os docs

Este filtro tentará primeiro coagir ambos os valores para inteiros … Strings que podem ser coagidos para inteiros serão sumdos, não concatenados

Se ambas as variables ​​forem inteiras, o resultado seria inesperado.

Eu mudei a hierarquia de pastas

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

e depois abaixo iria funcionar.

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

Agora é capaz de estender a página base.html.

Dos docs:

Esta tag pode ser usada de duas maneiras:

  • {% extends "base.html" %} (com aspas) usa o valor literal “base.html” como o nome do modelo pai a ser estendido.
  • {% extends variable %} usa o valor da variável. Se a variável for avaliada como uma string, o Django usará essa string como o nome do template pai. Se a variável avaliar um object Template, o Django usará esse object como modelo pai.

Então parece que você não pode usar um filtro para manipular o argumento. Na visualização de chamada, você deve instanciar o modelo de ancestral ou criar uma variável de string com o caminho correto e passá-lo com o contexto.

Dê uma olhada no filtro de add .

Edit: Você pode encadear filtros, então você pode fazer “shop /” | add: shop_name | add: “/ base.html”. Mas isso não funcionará porque cabe à tag de modelo avaliar os filtros nos argumentos e estende os não.

Eu acho que você não pode fazer isso dentro de modelos.

@ resposta do erro é fundamentalmente certo, você deve estar usando uma tag de modelo para isso. No entanto, eu prefiro uma tag de template um pouco mais genérica que eu possa usar para realizar qualquer tipo de operação semelhante a esta:

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

e então você pode usá-lo assim em seu modelo:

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

Como o comentário menciona, essa tag de modelo é particularmente útil para informações que podem ser repetidas em todo o modelo, mas requerem lógica e outras coisas que irão atrapalhar seus modelos ou em instâncias onde você deseja reutilizar dados passados ​​entre modelos por blocos:

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

e depois:

 {{ meta_title }}    

Crédito para a tag captureas é devido aqui: https://www.djangosnippets.org/snippets/545/

Eu achei que trabalhar com a tag {% with %} era um tanto trabalhoso. Em vez disso, criei a seguinte tag de modelo, que deve funcionar em strings e inteiros.

 from django import template register = template.Library() @register.filter def concat_string(value_1, value_2): return str(value_1) + str(value_2) 

Em seguida, carregue a tag de modelo em seu modelo na parte superior usando o seguinte:

 {% load concat_string %} 

Você pode então usá-lo da seguinte maneira:

 123 

Eu pessoalmente achei isso muito mais limpo para se trabalhar.

Refira Concatenating Strings em Django Templates :

  1. Para versões anteriores do Django:

    {{“Mary teve um pouco” | stringformat: “s lamb.” }}

“Mary tinha um cordeirinho.”

  1. Outro:

    {{“Mary teve um pouco” | add: “cordeiro”. }}

“Mary tinha um cordeirinho.”

Você não pode fazer manipulação variável nos templates do django. Você tem duas opções, escreva sua própria tag de modelo ou faça isso,

extends não tem facilidade para isso. Coloque o caminho do modelo inteiro em uma variável de contexto e use-o, ou copie a tag de modelo existente e modifique-a adequadamente.