2011-08-22 57 views
6

有沒有辦法在Django模板中執行isinstance/issubclass?我意識到我可以編寫自己的模板標籤,但我很驚訝,這不可能讓我覺得我要麼做錯了什麼,要麼錯過了一些明顯的東西。Django模板中的IsInstance?

我希望顯示兩個不同的標記段,這取決於我在迭代收集時顯示哪種類型的項目。謝謝!

回答

5

如果所有這些繼承自一個公共基類型,但您需要知道它是哪種類型,那麼您可能只想在返回該類型的基礎上實現一個方法 - 然後您可以調用if foo.get_type == 'type1'(或其他)在您的模板中。

0

您在這裏丟失了一些東西:模板中唯一的邏輯應該處理模板渲染。 isinstance/issubclass顯然聞起來像是視圖邏輯,應該在視圖中。如果模板渲染依賴於這些功能(我猜它),你應該實現在視圖中的邏輯,而只是通過它需要知道模板:

# 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 %} 

記住:Django的模板引擎是記住,像設計師一樣有非程序員。

+4

嗯,我一般用感情認同,但我不太確定我會盡可能地採取這種做法。 我的用例是,我有一個項目的集合,所有的公共基類型,但在集合中混合。一個foo應該像這樣顯示,一個條應該像這樣顯示,類似,但稍有不同。 它們顯示的字段略有不同,因此顯示片段不同,所以很有可能會說{%if item.field_that_bars_have%}或類似,但這似乎很討厭。 – Ludo

+0

我想正確的方法來處理這個是創建一個自定義標記,render_result_item,或者可以選擇正確的顯示片段的東西。這樣一來,邏輯就停留在視圖模板之外,儘管這樣做的代價是讓我們的非程序員/設計師無法找到它。 或者我可以寫一個isinstance模板標籤。或者我可以在模型中添加一個get_type或其他東西。 我現在在散漫 - 感謝您的迴應:)。 – Ludo

8

我認爲這裏的一個簡單的模板過濾器適合最好的。實施起來非常快,而且很容易打電話。事情是這樣的:

在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])) 

在你的模板

{% load my_filters %} 

... 

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

雖然上面是一個示例代碼(未測試),我相信它應該工作。 有關自定義模板過濾器的詳細信息,請參閱the django documentation

編輯:編輯答案表明,過濾器參數實際上是一個字符串,而不是一個Python類

+0

不得不引用模型的完整路徑使得這個解決方案在後端重構時很脆弱,再加上它需要模板/ html設計器來了解這些路徑。如果你的團隊被分成後端程序員和模板設計師,那麼這並不是最好的方法。 –

+0

我完全同意。這裏的意圖是回答這個問題。這顯然不是在您的模板中執行條件內容的最佳做法。 – ppetrid