2010-01-16 22 views
5

Vấn đề là nếu tôi gọi một templatetag thành một khối và nó điền vào tôi một biến thể với ngữ cảnh thông thường [varname] = something, thì nếu tôi cần biến đó chặn, tôi phải gọi lại lần nữa là templatetag. Điều này cho tôi có nghĩa là các truy vấn db bổ sung, thực sự là điều tôi đang cố tránh.Phạm vi Django templatetag buộc tôi phải thực hiện thêm các truy vấn

templatetag này được gọi trong một mẫu cơ sở được mở rộng bởi nhiều mẫu khác, vì vậy tôi không thể chỉ thay đổi tất cả các quan điểm để vượt qua một cái gì đó với bối cảnh, nó làm cho không có ý nghĩa (nguyên tắc WET?)

Ngay cả bộ xử lý ngữ cảnh sẽ không tốt vì tôi không muốn gọi cho mỗi trang được hiển thị trên trang web, ngay cả những trang không dựa trên trên mẫu đó.

Tôi đã suy nghĩ về cách viết một templatetag mà sẽ sử dụng các cấu trúc ngữ cảnh nội bộ để đặt biến trong bối cảnh toàn cầu, nhưng tôi cảm thấy quá tội lỗi khi làm điều đó.

Bạn giải quyết vấn đề này như thế nào?

Trả lời

0

Bạn chỉ đang cố gắng giảm số lượng truy vấn cơ sở dữ liệu hoặc bạn đang tìm kiếm giải pháp thông minh?

Nếu đó là cũ, tôi chắc chắn sẽ đi với bộ nhớ đệm. Bộ nhớ đệm sẽ làm việc trong trường hợp của bạn? Nếu không, có lẽ bạn có thể đặt bộ nhớ đệm trong mã thẻ mẫu (giả sử nó không phải là một trong những mẫu thẻ của riêng Django của bạn sử dụng)?

+0

Bộ nhớ đệm ở đây trông giống như bắn một con bướm bằng súng máy! –

3

Bạn đã nói, "Templatetag này được gọi trong mẫu cơ bản được mở rộng bởi nhiều mẫu khác."

Câu hỏi đặt ra là: thẻ này được gọi từ trong một khối được đặt tên? Nếu đó là sau đó bạn có một vài vấn đề tiềm năng.

  1. {% block %} đẩy một lệnh mới vào ngăn xếp bối cảnh và bật lên khi nó đạt đến `{% endblock%} phù hợp '. Điều này có nghĩa là bất kỳ giá trị ngữ cảnh nào được tạo ra trong khi trong khối về cơ bản đã biến mất khỏi phạm vi trên khối thoát.

  2. Nếu khối này bị ghi đè bởi một số mẫu khác mở rộng mẫu cơ sở, giá trị có thể không có sẵn trừ khi bạn thực hiện {{block.super}} và thậm chí sau đó tôi không chắc chắn giá trị sẽ có sẵn cho mẫu làm việc mở rộng.

Nếu thẻ không phải là gọi từ bên trong một {% block %} thì giá trị bối cảnh nên có sẵn cho tất cả các mã mà sau nó, hoặc trong các mẫu cơ bản, bất kỳ bao gồm các mẫu và (tôi nghĩ) bất kỳ mở rộng mẫu.

Đây là một trong những trường hợp xây dựng bộ kiểm tra cẩn thận có thể giúp bạn tiết kiệm thời gian và nước mắt.

Hoặc, nếu bạn luôn truy cập vào giá trị này, bạn có thể chỉ cần đặt nó trong một context processor để tính khả dụng của nó được đảm bảo.

Cập nhật nhận xét: OK, đến lúc mang súng lớn!Một trong những lỗi khó chịu nhất, lâu dài trong các mẫu Django là các hàm callables (tức là các hàm) là các giá trị ngữ cảnh cấp cao nhất (ngược lại với các hàm là giá trị dict/phương thức của giá trị ngữ cảnh) không được gọi ! Vé này đã quá 2 tuổi và mất khoảng 10 dòng mã để sửa. Chúng tôi có một số cuộc gọi DB trọng lượng nặng mà chúng tôi chỉ muốn xảy ra nếu bộ nhớ cache mẫu đã hết hạn. Vì vậy, chúng tôi a) MonkeyPatched mẫu _resolve_lookup() mã để khắc phục sự cố có thể gọi và sau đó b) chức năng cà ri để có tất cả các tham số cần thiết nếu cần, vì bạn không thể chuyển tham số cho các hàm trong "ngôn ngữ" mẫu.

+0

Nếu mẫu mà anh ta đang gọi thẻ cũng đang mở rộng một mẫu khác, thì hãy gọi một thẻ mẫu sửa đổi ngữ cảnh bên ngoài một khối thực sự không ảnh hưởng đến bất kỳ thứ gì. Tôi đoán đây là tình huống của anh ấy. –

+0

có, gọi nó bên ngoài một khối không hoạt động. Điều này là do tôi đang mở rộng một mẫu khác. –

2

Tôi nghĩ bạn đã mô tả chính xác các giới hạn trong tình huống này. Các giải pháp duy trì nhất có thể sẽ liên quan đến việc tái cơ cấu chuỗi thừa kế mẫu của bạn, mặc dù khó có thể nói mà không biết chi tiết. Bạn có thể giới thiệu một mẫu mới trong hệ thống phân cấp thừa kế, có lẽ ở đâu đó gần đỉnh của kim tự tháp nhưng nó chỉ được thừa hưởng bởi các mẫu cần dữ liệu này, với một khối bao gồm toàn bộ vùng mà bạn cần dữ liệu này? Khối lớn đó sau đó có thể được chia nhỏ thành các khối nhỏ hơn mà các mẫu kế thừa sẽ ghi đè lên. Nếu bạn gọi templatetag của bạn ở đầu khối đó, tất cả các khối bên trong nó (bao gồm cả các mẫu kế thừa) sẽ có quyền truy cập vào dữ liệu.

Cập nhật: Tôi không thể nói nhiều mà không nhìn thấy mẫu của bạn, nhưng giới thiệu một mẫu mới ở giữa chuỗi thừa kế rất hiếm khi liên quan đến việc "thay đổi tất cả các mẫu" trong cấu trúc thừa kế thông thường. chỉ thay đổi một hoặc hai mẫu khác. Và tôi nghĩ điều tôi đang đề xuất thực sự không phải là hack, nó chỉ là thiết kế tốt hơn. Nếu bạn cần một phần dữ liệu nhất định trong một số phần nhất định trên trang web của mình và không phải các phần khác, thì phải là một mẫu đơn cụ thể mà bạn có thể trỏ tới và nói "mẫu này đại diện cho lớp logic mà tại đó đoạn dữ liệu này được giới thiệu, và bao gồm các phần của trang web nơi dữ liệu đó là cần thiết. "

+0

Cảm ơn bạn carl, Thật không may là hai khối là 1) thanh bên trái, 2) thanh bên phải. Đặt chúng xuống dưới một khối chung sẽ rất khó khăn với bố cục hiện tại của các mẫu, và tôi không muốn phải thay đổi tất cả các mẫu chỉ vì tôi không thể đọc một biến trong hai khối, tôi xem nó là một hack. Cảm ơn các đề xuất! –

0

Chỉ cần đi qua thủ thuật này từ Liviu, Agile Bear (tất cả tín dụng đi với anh)

Thay vì làm

context['some_var']='some value' 

làm

context.dicts[0]['some_var']='some value' 

Có thể không phải là một by-the-book thực hành mã hóa nhưng hoạt động đủ tốt

Các vấn đề liên quan