2011-08-22 26 views
6

Có cách nào để làm isinstance/issubclass trong một mẫu Django? Tôi nhận ra tôi có thể viết templatetag của riêng mình, nhưng tôi ngạc nhiên rằng điều này không thể khiến tôi nghĩ rằng mình đang làm điều gì đó sai hoặc thiếu điều gì đó hiển nhiên.IsInstance trong mẫu Django?

Tôi muốn hiển thị hai phân đoạn đánh dấu khác nhau, tùy thuộc vào loại mục tôi đang hiển thị trong khi lặp lại trên bộ sưu tập của mình. Cảm ơn!

Trả lời

5

Nếu tất cả được thừa kế từ loại cơ sở chung, nhưng bạn cần biết loại đó là gì, bạn có thể chỉ cần triển khai phương thức trên cơ sở trả về loại - sau đó bạn có thể gọi if foo.get_type == 'type1' (hoặc bất kỳ thứ gì) trong mẫu của bạn.

0

Bạn đang thiếu thứ gì đó ở đây: logic duy nhất trong mẫu được cho là xử lý hiển thị mẫu. isinstance/issubclass rõ ràng có mùi giống như chế độ xem logic và phải ở chế độ xem. Nếu mẫu vẽ phụ thuộc vào những chức năng (mà tôi đoán nó), bạn nên thực hiện logic trong giao diện, và chỉ cần vượt qua mẫu những gì nó cần phải biết:

# in the view: 
if isinstance(some_obj, SomeClass): 
    do_fancy_template_stuff = True 
else: 
    do_fancy_template_stuff = False 

# in the template: 
{% if do_fancy_template_stuff %} 
    <fancy_template_stuff /> 
{% endif %} 

Hãy nhớ rằng: động cơ django khuôn mẫu là đã tạo ra những người không phải là lập trình viên, giống như các nhà thiết kế.

+4

Hmmm, tôi đồng ý với những tình cảm nói chung, nhưng tôi không dám chắc tôi đi xa như vậy. Trường hợp sử dụng của tôi là, tôi có một tập hợp các mục, tất cả loại cơ sở chung, nhưng được trộn lẫn trong bộ sưu tập. Một foo sẽ hiển thị như thế này, một thanh sẽ hiển thị như thế, loại tương tự, nhưng hơi khác nhau. Chúng có các trường hơi khác nhau để hiển thị, do đó có các mảng hiển thị khác nhau, do đó, bạn có thể nói {% if item.field_that_bars_have%} hoặc tương tự, nhưng điều đó có vẻ khó chịu. – Ludo

+0

Tôi đoán cách chính xác để xử lý việc này là tạo thẻ tùy chỉnh, render_result_item hoặc thứ gì đó có thể chọn đoạn hiển thị chính xác. Bằng cách đó, logic vẫn ở ngoài khuôn mẫu khung nhìn, mặc dù với chi phí đặt nó ở đâu đó mà người không lập trình/nhà thiết kế của chúng tôi sẽ không thể tìm thấy nó. Hoặc tôi có thể viết templatetag isinstance. Hoặc tôi có thể thêm một get_type hoặc một cái gì đó cho mô hình. Tôi hiện đang đánh bạc - cảm ơn phản hồi của bạn :). – Ludo

8

Tôi nghĩ rằng một bộ lọc mẫu đơn giản ở đây phù hợp nhất. Nó thực sự nhanh chóng để thực hiện và dễ dàng để gọi. Một cái gì đó như thế này:

trong templatetags/my_filters.py:

from django import template 
from django.utils.importlib import import_module 

register = template.Library() 

@register.filter 
def isinst(value, class_str): 
    split = class_str.split('.') 
    return isinstance(value, getattr(import_module('.'.join(split[:-1])), split[-1])) 

trong mẫu của bạn:

{% load my_filters %} 

... 

{% if myvar|isinst:"mymodule.MyClass" %} 
...do your stuff 
{% endif %} 

Mặc dù ở trên là một mẫu mã (không kiểm tra), tôi tin rằng nó sẽ hoạt động. Để biết thêm thông tin về mẫu bộ lọc tùy chỉnh xin vui lòng xem the django documentation

EDIT: Edited các câu trả lời để chứng minh rằng đối số bộ lọc thực sự là một chuỗi và không một con trăn Lớp

+0

Phải tham khảo đường dẫn đầy đủ của một mô hình làm cho giải pháp này trở nên mong manh để tái cấu trúc trong phần phụ trợ, cộng với nó yêu cầu trình thiết kế mẫu/html biết các đường dẫn này. Không phải là cách tốt nhất để làm điều đó nếu nhóm của bạn được chia thành các lập trình viên phụ trợ và nhà thiết kế mẫu. –

+0

Tôi hoàn toàn đồng ý.Ý định ở đây là trả lời câu hỏi; đây rõ ràng không phải là phương pháp hay nhất để thực hiện các công cụ có điều kiện trong các mẫu của bạn. – ppetrid