2009-09-11 37 views
73

Tôi muốn cung cấp cùng một nội dung bên trong 2 tệp cơ sở khác nhau.mẫu django: bao gồm và mở rộng

Vì vậy, tôi đang cố gắng để làm điều này:

page1.html:

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

page2.html:

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

Vấn đề là tôi dường như không thể sử dụng cả hai mở rộng và bao gồm. Có cách nào để làm điều đó không? Và nếu không, làm thế nào tôi có thể thực hiện được những điều trên?

commondata.html ghi đè một khối được chỉ định trong cả hai base1.html và base2.html

Mục đích của việc này là để cung cấp cùng một trang trong cả pdf và html định dạng, nơi mà các định dạng là hơi khác nhau. Các câu hỏi trên mặc dù đơn giản hóa những gì tôi đang cố gắng để làm như vậy nếu tôi có thể nhận được một câu trả lời cho rằng nó sẽ giải quyết vấn đề của tôi.

Trả lời

83

Khi bạn sử dụng thẻ mẫu mở rộng, bạn đang nói rằng mẫu hiện tại mở rộng mẫu khác - đó là mẫu con, phụ thuộc vào mẫu chính. Django sẽ xem xét mẫu con của bạn và sử dụng nội dung của nó để điền bố mẹ.

Mọi thứ bạn muốn sử dụng trong mẫu con phải nằm trong các khối, mà Django sử dụng để điền bố mẹ. Nếu bạn muốn sử dụng một tuyên bố bao gồm trong mẫu con đó, bạn phải đặt nó trong một khối, cho Django để làm cho tinh thần của nó. Nếu không nó chỉ không có ý nghĩa và Django không biết phải làm gì với nó.

Tài liệu Django có một số ví dụ thực sự tốt về việc sử dụng các khối để thay thế các khối trong mẫu chính. Thông tin

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

+1

commondata.html tôi có khối được xác định trong đó. Nhưng nó không phải là thay thế khối tempalte của cha mẹ ... Nếu thay vì làm một bao gồm tôi viết dữ liệu chính xác hai lần trong cả hai page1.html và page2.html sau đó tất nhiên nó hoạt động.Nhưng tôi muốn đưa ra tính phổ biến trong commondata.html. –

+0

Tôi sẽ cố gắng trong một khối nhưng tôi nghĩ rằng tôi đã thử trước đó ... –

+0

Dường như làm việc, tôi nhớ đã cố gắng này nhưng tôi phải có một lỗi đánh máy hoặc một cái gì đó vào thời điểm đó khiến nó không hoạt động. –

9

Thông tin thêm về lý do tại sao nó không được làm việc cho tôi trong trường hợp nó giúp con người trong tương lai:

Lý do tại sao nó không được làm việc là {% bao gồm%} trong django doesn' t giống như các nhân vật đặc biệt như dấu nháy đơn ưa thích. Dữ liệu mẫu tôi đã cố gắng đưa vào đã được dán từ từ. Tôi đã phải tự xóa tất cả các ký tự đặc biệt này và sau đó nó được bao gồm thành công.

64

Từ tài liệu Django:

Các bao gồm thẻ nên được coi là một thực hiện "render subtemplate này và bao gồm HTML", chứ không phải là "phân tích subtemplate này và bao gồm nội dung của nó như thể nó là một phần của cha mẹ ". Điều này có nghĩa là không có trạng thái chia sẻ giữa các mẫu được bao gồm - mỗi mẫu bao gồm là một quá trình kết xuất hoàn toàn độc lập.

Vì vậy, Django không lấy bất kỳ khối nào từ commondata.html của bạn và không biết phải làm gì với khối kết xuất html bên ngoài.

2

Đã thêm để tham khảo những người tương lai tìm thấy thông tin này qua google: Bạn có thể muốn xem thẻ {% overextend%} do thư viện gác lửng cung cấp cho các trường hợp như thế này.

3

Bạn không thể kéo khối từ tệp được bao gồm vào mẫu con để ghi đè các khối của mẫu chính.Tuy nhiên, bạn có thể chỉ định một phụ huynh trong một biến và có khuôn mẫu cơ sở được chỉ định trong ngữ cảnh.

Từ documentation:

{% kéo dài biến%} sử dụng giá trị của biến. Nếu biến đánh giá thành chuỗi, Django sẽ sử dụng chuỗi đó làm tên của mẫu gốc. Nếu biến đánh giá đối tượng Mẫu, Django sẽ sử dụng đối tượng đó làm mẫu gốc.

Thay vì riêng "page1.html" và "page2.html", hãy đặt {% extends base_template %} ở đầu "commondata.html". Và trong chế độ xem của bạn, hãy xác định base_template là "base1.html" hoặc "base2.html".

1

Chỉnh sửa ngày 10 tháng 12 năm 2015: Như đã nêu trong các nhận xét, ssi không còn được dùng kể từ phiên bản 1.8. Theo tài liệu:

Thẻ này đã không còn được dùng nữa và sẽ bị xóa trong Django 1.10. Sử dụng thẻ bao gồm thay thế.


Theo tôi, bên phải (tốt nhất) câu trả lời cho câu hỏi này là một trong những từ podshumok, vì nó giải thích tại sao hành vi của bao gồm khi được sử dụng cùng với thừa kế.

Tuy nhiên, tôi đã hơi ngạc nhiên mà không ai đề cập đến thẻ ssi được cung cấp bởi hệ thống khuôn mẫu Django, được thiết kế đặc biệt cho inline bao gồm một mảnh bên ngoài của văn bản. Ở đây, nội tuyến có nghĩa là văn bản bên ngoài sẽ không được diễn giải, phân tích cú pháp hoặc nội suy, nhưng chỉ đơn giản là "sao chép" bên trong mẫu gọi.

Vui lòng tham khảo tài liệu để biết thêm chi tiết (hãy nhớ kiểm tra phiên bản Django thích hợp của bạn trong bộ chọn ở phần dưới bên phải của trang).

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

Từ các tài liệu:

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 

Cẩn thận cũng của tác động an ninh của kỹ thuật này và cũng có thể của ALLOWED_INCLUDE_ROOTS cần xác định, mà phải được bổ sung vào file cài đặt.

+1

Lưu ý, trong số 1.8, ssi đã không được chấp thuận để ủng hộ Bao gồm. [https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#std:templatetag-include](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/# std: templatetag-include) –

5

Điều này cần thực hiện thủ thuật cho bạn: hãy đưa thẻ vào bên trong phần khối.

page1.html:

{% extends "base1.html" %} 

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

page2.html:

{% extends "base2.html" %} 

{% block bar %} 
    {% include "commondata.html" %} 
{% endblock %} 
Các vấn đề liên quan