有沒有辦法在Django模板中執行isinstance/issubclass?我意識到我可以編寫自己的模板標籤,但我很驚訝,這不可能讓我覺得我要麼做錯了什麼,要麼錯過了一些明顯的東西。Django模板中的IsInstance?
我希望顯示兩個不同的標記段,這取決於我在迭代收集時顯示哪種類型的項目。謝謝!
有沒有辦法在Django模板中執行isinstance/issubclass?我意識到我可以編寫自己的模板標籤,但我很驚訝,這不可能讓我覺得我要麼做錯了什麼,要麼錯過了一些明顯的東西。Django模板中的IsInstance?
我希望顯示兩個不同的標記段,這取決於我在迭代收集時顯示哪種類型的項目。謝謝!
如果所有這些繼承自一個公共基類型,但您需要知道它是哪種類型,那麼您可能只想在返回該類型的基礎上實現一個方法 - 然後您可以調用if foo.get_type == 'type1'
(或其他)在您的模板中。
您在這裏丟失了一些東西:模板中唯一的邏輯應該處理模板渲染。 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的模板引擎是記住,像設計師一樣有非程序員。
我認爲這裏的一個簡單的模板過濾器適合最好的。實施起來非常快,而且很容易打電話。事情是這樣的:
在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類
不得不引用模型的完整路徑使得這個解決方案在後端重構時很脆弱,再加上它需要模板/ html設計器來了解這些路徑。如果你的團隊被分成後端程序員和模板設計師,那麼這並不是最好的方法。 –
我完全同意。這裏的意圖是回答這個問題。這顯然不是在您的模板中執行條件內容的最佳做法。 – ppetrid
嗯,我一般用感情認同,但我不太確定我會盡可能地採取這種做法。 我的用例是,我有一個項目的集合,所有的公共基類型,但在集合中混合。一個foo應該像這樣顯示,一個條應該像這樣顯示,類似,但稍有不同。 它們顯示的字段略有不同,因此顯示片段不同,所以很有可能會說{%if item.field_that_bars_have%}或類似,但這似乎很討厭。 – Ludo
我想正確的方法來處理這個是創建一個自定義標記,render_result_item,或者可以選擇正確的顯示片段的東西。這樣一來,邏輯就停留在視圖模板之外,儘管這樣做的代價是讓我們的非程序員/設計師無法找到它。 或者我可以寫一個isinstance模板標籤。或者我可以在模型中添加一個get_type或其他東西。 我現在在散漫 - 感謝您的迴應:)。 – Ludo