장고 템플릿에서 문자열을 연결하는 방법은 무엇입니까?


191

Django 템플릿 태그에 문자열을 연결하고 싶습니다.

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

여기 shop_name내 변수가 있으며 나머지 경로와 이것을 연결하고 싶습니다.

내가 가지고 shop_name=example.com있고 결과를 확장하고 싶다고 가정 해보십시오 shop/example.com/base.html.

답변:


380

함께 사용 :

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

2
확장 태그 대신 포함 태그를 사용하기 때문에이 답변에 완전히 혼란 스럽지만 분명히 작동합니다. 비록 그것이 작동하고 의미 적으로 더 정확하고 혼동을 줄이면서 아산 자신의 대답을 추천 할 것이지만.
gitaarik

15
이것은 작동 할 수 있지만 장고 템플릿에서 문자열을 연결하는 일반적인 대답으로 간주해서는 안됩니다. 참조 stackoverflow.com/a/23783666/781695
사용자

장고 문서에서 말하는 것처럼 "정수로 강제 변환 할 수있는 문자열은 연결되지 않고 합산됩니다."예를 들어 모델 객체의 기본 키를 연결하려는 경우 (고유 캐시 키를 만드는 데 유용 할 수 있음) 작업.
zen11625

나는 이것이 전혀 탈출하지 못한다고 생각 shop_name하므로 위험합니다.
Flimm

이미 언급했듯이 이것은 문자열에서만 작동합니다! 당신이 번역하면 shop_name뷰에서 컨텍스트에 전달하기 전에의를 get_context_data사용하여 번역되어 있는지 확인 ugettext대신 ugettext_lazy.
Kim

111

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이 말한대로 사용하십시오.

{% load <appname>_extras %}

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

피해야 할 이유 add:

문서 에 따르면

이 필터는 먼저 두 값을 모두 정수로 강제하려고 시도합니다 ... 정수로 강제 할 수있는 문자열은 합산 되지 않고 합산됩니다 ...

두 변수가 모두 정수이면 결과가 예상치 못한 것입니다.


@ register.filter (name = 'addstr')이 아니어야합니까?
seddonym

6
파이썬에 의해 정수로 강제 될 수있는 값으로 올바르게 작동하기 때문에 이것이 최선의 대답으로 표시되어야합니다.
zen11625

2
당신이 가장 "최대"로 하나없는 이유가 있기 때문에 내가 잘 모릅니다 당신의 권리입니다 대답은 "은 add"혼자 그냥 사용하지 않는 str()첫 번째 장소에서 작업하지 않았다 전혀를 나를 위해 당신의 솔루션은 완벽하게 작동하는 반면
Olivier Pons

1
당신의 대답은 저를 구했습니다!
Ljubisa Livac

6
템플릿 파일 맨 위에 사용자 정의 필터를로드해야합니다.{% load <appname>_extras %}
Susanne Peng

13

폴더 계층 구조를 변경했습니다

/shop/shop_name/base.html받는 사람 /shop_name/shop/base.html

아래에서 작동합니다.

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

이제 base.html 페이지를 확장 할 수 있습니다.


7

Django 템플릿에서 문자열 연결을 참조하십시오 .

  1. Django의 이전 버전의 경우 :

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

"메리에게는 작은 양이있었습니다."

  1. 그밖에:

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

"메리에게는 작은 양이있었습니다."


3

add필터를 살펴보십시오 .

편집 : 필터를 연결할 수 있으므로 할 수 있습니다 "shop/"|add:shop_name|add:"/base.html". 그러나 인수의 필터를 평가하는 것은 템플릿 태그에 달려 있기 때문에 작동하지 않으며 확장은 작동하지 않습니다.

템플릿 내에서는이 작업을 수행 할 수 없습니다.


이것은 작동하지 않을 것입니다. 경로 중간에 변수를 추가하고 싶습니다.
Ahsan

django 문서에 따라 연결되지 않은 것으로 만 필터 추가
Ahsan

문서에는 "정수로 강제 변환 할 수있는 문자열이 합산됩니다"라고 말합니다. 다른 문자열이 연결됩니다. 그러나 필터를 사용할 수 없기 때문에 그것은 실제로 어쨌든 중요하지 않습니다 :(
Daniel Hepper

2

문서에서 :

이 태그는 두 가지 방법으로 사용할 수 있습니다.

  • {% extends "base.html" %} (따옴표 포함)는 확장 할 상위 템플릿의 이름으로 리터럴 값 "base.html"을 사용합니다.
  • {% extends variable %}변수의 값을 사용합니다. 변수가 문자열로 평가되면 Django는 해당 문자열을 부모 템플릿의 이름으로 사용합니다. 변수가 Template 객체로 평가되면 Django는 해당 객체를 상위 템플릿으로 사용합니다.

따라서 인수를 조작하기 위해 필터를 사용할 수없는 것 같습니다. 호출 뷰에서 상위 템플리트를 인스턴스화하거나 올바른 경로로 문자열 변수를 작성하고 컨텍스트와 함께 전달해야합니다.


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/에 있습니다.


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>

나는 개인적으로 이것이 작업하기에 훨씬 더 깨끗하다는 것을 알았습니다.


0

장고 템플릿에서는 변수 조작을 수행 할 수 없습니다. 자신 만의 템플릿 태그를 작성하거나보기에서 두 가지 옵션이 있습니다.


내 요구 사항은 템플릿에서만 수행하므로 뷰 옵션은 도움이되지 않습니다. 또한 맞춤 템플릿 태그를 통해 시도했지만 {% extend .... %} 태그 뒤에 {% load concat %}가 있어야합니다. 그래서 지금 어떻게 할 수 있습니까?
Ahsan

문자열 형식과 인수를 허용하는 extended_extends 태그를 작성하십시오.
Paulo Scardine

기본 태그에 대한 사용자 정의 태그를 작성하는 방법의 예를 알려주시겠습니까?
Ahsan

0

extends이를위한 시설이 없습니다. 전체 템플릿 경로를 컨텍스트 변수에 넣고 사용하거나 기존 템플릿 태그를 복사하여 적절하게 수정하십시오.


답장을 보내 주셔서 감사합니다! 컨텍스트 변수의 경우 프로젝트 요구 사항으로 인해 view.py에서 설정해야합니다. 두 번째 예를 들어주세요.
Ahsan

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 }}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.