장고 템플릿 : 포함 및 확장


108

2 개의 다른 기본 파일에 동일한 콘텐츠를 제공하고 싶습니다.

그래서 이렇게하려고합니다.

page1.html :

{% extends "base1.html" %}
{% include "commondata.html" %}

page2.html :

{% extends "base2.html" %} 
{% include "commondata.html" %}

문제는 내가 extends와 include를 모두 사용할 수 없다는 것입니다. 그렇게 할 수있는 방법이 있습니까? 그렇지 않은 경우 어떻게 위의 작업을 수행 할 수 있습니까?

commondata.html은 base1.html 및 base2.html 모두에 지정된 블록을 대체합니다.

그 목적은 형식이 약간 다른 pdf 및 html 형식으로 동일한 페이지를 제공하는 것입니다. 위의 질문은 내 문제를 해결할 것이라는 답을 얻을 수 있다면 내가하려는 작업을 단순화합니다.

답변:


110

extends 템플릿 태그를 사용하면 현재 템플릿이 다른 템플릿을 확장한다는 것을 의미합니다. 즉, 부모 템플릿에 종속 된 자식 템플릿입니다. Django는 자식 템플릿을보고 해당 콘텐츠를 사용하여 부모를 채 웁니다.

자식 템플릿에서 사용하려는 모든 것은 Django가 부모를 채우기 위해 사용하는 블록 내에 있어야합니다. 하위 템플릿에 include 문을 사용하려면 Django가 이해할 수 있도록 블록 안에 넣어야합니다. 그렇지 않으면 말이 안되며 Django는 그것으로 무엇을 해야할지 모릅니다.

Django 문서에는 부모 템플릿의 블록을 대체하기 위해 블록을 사용하는 몇 가지 좋은 예가 있습니다.

https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance


1
내 commondata.html에는 블록이 정의되어 있습니다. 그러나 그것은 부모 tempalte의 블록을 대체하지 않습니다 ... include를 수행하는 대신 page1.html과 page2.html 모두에 정확한 데이터를 두 번 작성하면 물론 작동합니다. 하지만 저는 그 공통성을 commondata.html로 빼내고 싶습니다.
Net Citizen

작동하는 것 같습니다. 나는 이것을 시도한 것을 기억하지만 그 당시에 오타 또는 무언가가 작동하지 않게 한 것 같습니다.
Net Citizen

1
내가 처음으로 작동하지 않은 이유는 아래의 내 대답을 참조하십시오. 내가 질문 한 질문에 올바르게 대답했기 때문에 수락 된 대답을 남겨 드리겠습니다.
Net Citizen

80

Django 문서에서 :

include 태그는 "이 서브 템플릿을 구문 분석하고 부모의 일부인 것처럼 내용을 포함"하는 것이 아니라 "이 서브 템플릿 렌더링 및 HTML 포함"의 구현으로 간주되어야합니다. 이는 포함 된 템플릿간에 공유 상태가 없음을 의미하며 각 포함은 완전히 독립적 인 렌더링 프로세스입니다.

따라서 Django는 commondata.html에서 블록을 가져 오지 않으며 블록 외부에서 렌더링 된 html로 무엇을해야하는지 알지 못합니다.


32

이것은 당신을 위해 트릭을 할 것입니다 : 블록 섹션 안에 include 태그를 넣으십시오.

page1.html :

{% extends "base1.html" %}

{% block foo %}
   {% include "commondata.html" %}
{% endblock %}

page2.html :

{% extends "base2.html" %}

{% block bar %}
   {% include "commondata.html" %}
{% endblock %}

1
완전한. 나를 위해 작동합니다.
Trupti M Panchal

13

미래의 사람들에게 도움이 될 경우를 대비하여 왜 작동하지 않았는 지에 대한 자세한 정보 :

작동하지 않는 이유는 django의 {% include %}가 멋진 아포스트로피와 같은 특수 문자를 좋아하지 않기 때문입니다. 포함시키려는 템플릿 데이터는 단어에서 붙여 넣었습니다. 이러한 특수 문자를 모두 수동으로 제거해야하며 성공적으로 포함되었습니다.


3

포함 된 파일의 블록을 하위 템플릿으로 가져와 상위 템플릿의 블록을 재정의 할 수 없습니다. 그러나 변수에 부모를 지정하고 컨텍스트에 기본 템플릿을 지정할 수 있습니다.

로부터 문서 :

{% extends variable %}는 변수 값을 사용합니다. 변수가 문자열로 평가되면 Django는 해당 문자열을 부모 템플릿의 이름으로 사용합니다. 변수가 Template 객체로 평가되면 Django는 해당 객체를 부모 템플릿으로 사용합니다.

별도의 "page1.html"및 "page2.html"대신 "commondata.html" {% extends base_template %}의 맨 위에 배치 하십시오. 그런 다음보기에서 base_template"base1.html"또는 "base2.html"로 정의하십시오.


2

Google을 통해 이것을 발견하는 미래의 사람들을 위해 추가되었습니다. 이와 같은 경우 메 자닌 라이브러리에서 제공하는 {% overextend %} 태그를 살펴볼 수 있습니다.


1

2015 년 12 월 10 일 편집 : 주석에서 지적했듯이 ssi 는 버전 1.8부터 더 이상 사용되지 않습니다. 문서에 따르면 :

이 태그는 더 이상 사용되지 않으며 Django 1.10에서 제거됩니다. 대신 포함 태그를 사용하십시오.


내 생각에이 질문에 대한 올바른 (최상의) 대답은 podshumok의 답변입니다 . 상속과 함께 사용할 때 include의 동작이 이유를 설명하기 때문입니다.

그러나 외부 텍스트를 포함하여 인라인 용으로 특별히 설계된 Django 템플릿 시스템에서 제공 하는 ssi 태그에 대해 언급 한 사람이 아무도 없다는 사실에 다소 놀랐습니다 . 여기서 인라인 은 외부 텍스트가 해석, 구문 분석 또는 보간되지 않고 단순히 호출 템플릿 내부에서 "복사"됨을 의미합니다.

자세한 내용은 문서를 참조하세요 (페이지 오른쪽 하단의 선택기에서 적절한 Django 버전을 확인하세요).

https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ssi

문서에서 :

ssi
Outputs the contents of a given file into the page.
Like a simple include tag, {% ssi %} includes the contents of another file
 which must be specified using an absolute path  in the current page

이 기술의 보안 의미와 설정 파일에 추가되어야하는 필수 ALLOWED_INCLUDE_ROOTS 정의도주의하십시오.


1
1.8부터 ssi는 Include 대신 더 이상 사용되지 않습니다. https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#std:templatetag-include
Tim S.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.