django şablonları: içerir ve genişletir


109

Aynı içeriği 2 farklı temel dosya içinde sunmak istiyorum.

Bu yüzden bunu yapmaya çalışıyorum:

page1.html:

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

page2.html:

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

Sorun şu ki, hem extends hem de include'i kullanamıyorum. Bunu yapmanın bir yolu var mı? Ve değilse, yukarıdakileri nasıl başarabilirim?

commondata.html, hem base1.html hem de base2.html'de belirtilen bir bloğu geçersiz kılar

Bunun amacı, biçimlendirmenin biraz farklı olduğu aynı sayfayı hem pdf hem de html biçiminde sağlamaktır. Yukarıdaki soru, yapmaya çalıştığım şeyi basitleştiriyor, eğer bir cevap alabilirsem sorunumu çözecek.

Yanıtlar:


110

Extends şablon etiketini kullandığınızda, geçerli şablonun bir başkasını genişlettiğini - bunun bir ana şablona bağlı olarak bir alt şablon olduğunu söylüyorsunuz. Django, alt şablonunuza bakacak ve içeriğini üst şablonu doldurmak için kullanacaktır.

Bir alt şablonda kullanmak istediğiniz her şey, Django'nun ebeveyni doldurmak için kullandığı bloklar içinde olmalıdır. Bu alt şablonda bir include ifadesi kullanmak istiyorsanız, Django'nun anlamlandırması için onu bir bloğun içine koymalısınız. Aksi takdirde bir anlam ifade etmez ve Django onunla ne yapacağını bilemez.

Django dokümantasyonu, üst şablondaki blokları değiştirmek için blokları kullanmanın gerçekten iyi birkaç örneğine sahiptir.

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


1
benim commondata.html dosyamda tanımlı blok var. Ama ana tempalte bloğunun yerini almıyor ... Bir include yapmak yerine tam veriyi page1.html ve page2.html'de iki kez yazarsam, o zaman tabii ki işe yarıyor. Ancak bu ortak noktayı commondata.html'de hesaba katmak istiyorum.
Net Citizen

İşe yarıyor gibi görünüyor, bunu denediğimi hatırlıyorum ama o sırada çalışmamasına neden olan bir yazım hatası ya da başka bir şey olmalı.
Net Citizen

1
Neden benim için işe yaramadığı için aşağıdaki cevabıma bakın, yine de sorduğum soruyu doğru cevapladığınız için sizi kabul edilen cevaba bırakacağım.
Net Citizen

80

Django belgelerinden:

İnclude etiketi, "bu alt şablonu ayrıştır ve içeriğini üst öğenin bir parçasıymış gibi dahil et" olarak değil, "bu alt şablonu oluştur ve HTML'yi içer" in bir uygulaması olarak düşünülmelidir. Bu, dahil edilen şablonlar arasında paylaşılan bir durumun olmadığı anlamına gelir - her bir dahil etme tamamen bağımsız bir oluşturma sürecidir.

Yani Django, commondata.html dosyanızdan herhangi bir blok almaz ve oluşturulan html dış bloklarla ne yapacağını bilemez.


32

Bu sizin için hile yapmalı: bir blok bölümünün içine include etiketi koyun.

page1.html:

{% extends "base1.html" %}

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

page2.html:

{% extends "base2.html" %}

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

1
Mükemmel. Benim için çalışıyor.
Trupti M Panchal

13

Gelecekteki insanlara yardımcı olma ihtimaline karşı neden benim için işe yaramadığı hakkında daha fazla bilgi:

Çalışmamasının nedeni, django'daki {% include%} 'nin süslü kesme işareti gibi özel karakterlerden hoşlanmamasıdır. Dahil etmeye çalıştığım şablon verileri word'den yapıştırıldı. Tüm bu özel karakterleri manuel olarak kaldırmak zorunda kaldım ve sonra başarıyla dahil ettim.


3

Ana şablonun bloklarını geçersiz kılmak için dahil edilen bir dosyadan blokları bir alt şablona çekemezsiniz. Ancak, bir değişkende bir üst öğe belirtebilir ve bağlamda temel şablonun belirtilmesini sağlayabilirsiniz.

Gönderen belgeler :

{% extends variable%} değişkenin değerini kullanır. Değişken bir dizge olarak değerlendirilirse, Django bu dizeyi ana şablonun adı olarak kullanır. Değişken bir Şablon nesnesi olarak değerlendirilirse, Django bu nesneyi ana şablon olarak kullanır.

Ayrı {% extends base_template %}"sayfa1.html" ve "sayfa2.html" yerine, "commondata.html" nin üstüne koyun . Ve sonra görünümünüzde base_template"base1.html" veya "base2.html" olarak tanımlayın .


2

Bunu google aracılığıyla bulan gelecekteki kişilere referans olması için eklendi: Buna benzer durumlar için mezzanine kitaplığı tarafından sağlanan {% overerextend%} etiketine bakmak isteyebilirsiniz.


1

Düzenleme 10 Aralık 2015 : Yorumlarda belirtildiği gibi, ssi sürüm 1.8'den beri kullanımdan kaldırılmıştır. Belgelere göre:

Bu etiket kullanımdan kaldırılmıştır ve Django 1.10'da kaldırılacaktır. Bunun yerine include etiketini kullanın.


Kanımca, bu sorunun doğru (en iyi) cevabı podshumok'tan gelen cevaptır , çünkü kalıtımla birlikte kullanıldığında dahil etme davranışının nedenini açıklar.

Bununla birlikte, Django şablonlama sistemi tarafından sağlanan ssi etiketinden kimsenin bahsetmediğine şaşırdım , özellikle de harici bir metin parçası dahil olmak üzere satır içi için tasarlanmış . Burada, satır içi , harici metnin yorumlanmayacağı, ayrıştırılmayacağı veya enterpolasyon yapılmayacağı, yalnızca çağıran şablonun içinde "kopyalanacağı" anlamına gelir.

Lütfen daha fazla ayrıntı için belgelere bakın (sayfanın sağ alt kısmındaki seçicide uygun Django sürümünüzü kontrol ettiğinizden emin olun).

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

Belgelerden:

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

Ayrıca bu tekniğin güvenlik sonuçlarına ve ayrıca ayar dosyalarınıza eklenmesi gereken gerekli ALLOWED_INCLUDE_ROOTS tanımına dikkat edin.


1
1.8 itibariyle, ssi'nin Include lehine kullanımdan kaldırıldığına dikkat edin. https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#std:templatetag-include
Tim S.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.