Djangoのテンプレートの「スイッチケース」ステートメントの機能を取得するには?
-
05-09-2019 - |
質問
私は、Djangoのテンプレートに「スイッチ」のタグを持っているのリンクを見つけましたが、Iこれは何とかそれなしで実現することができるかどうかと思いまして。ジャンゴに付属しているだけのものを使用していますか?基本的にし、「が」複数のか「ifequal」ステートメントを使用して、他の方法は何ですか?
任意のヒント/提案を事前に感謝します。
解決
残念ながら、これはデフォルトのDjangoテンプレートエンジンでは不可能です。あなたはスイッチをエミュレートするために、このような醜いものを記述する必要があります。
{% if a %}
{{ a }}
{% else %}
{% if b %}
{{ b }}
{% else %}
{% if c %}
{{ c }}
{% else %}
{{ default }}
{% endif %}
{% endif %}
{% endif %}
か一つだけであれば条件が真であることができますし、デフォルトを必要としない場合ます。
{% if a %}
{{ a }}
{% endif %}
{% if b %}
{{ b }}
{% endif %}
{% if c %}
{{ c }}
{% endif %}
通常、テンプレートエンジンを使用すると、このコードは、Djangoのビューに代わりのテンプレートに移動しなければならないという印である何をしたい達成するために十分に強力でないとき。たとえばます:
# Django view
if a:
val = a
elif b:
val = b
elif c:
val = c
else:
val = default
# Template
{{ val }}
他のヒント
は、Djangoの1.4の時点では、{% elif %}
があります:
{% if a %}
thing
{% elif b %}
other thing
{% elif c %}
another thing
{% endif %}
前のレスポンダに:ユースケースを理解しなければ、仮定を作り、質問者を批判してきました。 @Berは確かに質問者によって暗示されていない「すべての場所で」と言います。公平ではない。
私はDjangoテンプレートで正確に一つの場所で{% switch %}
文をやりたい場合があります。それだけでなく、実際に読んで、一つの場所に属し、2ヶ所に分割し、簡単な条件付きロジックを取るためにビューとテンプレートの両方難しくなるだろう、Pythonのコードにswitch文と同等のものを移動することが便利ではありませんが、。
私は{% switch %}
(または{% if %}
)を想像することができ、多くの場合に有用であることには、いずれかを使用していないと、ビューでHTMLを置くことが必要です。それははるかに悪い罪だと{% if %}
が最初の場所に存在する理由です。 {% switch %}
も例外ではありません。
幸いなことに、Djangoは拡張可能であり、複数の人がスイッチを実装しています。チェックアウト:
from django import template
from django.template import Library, Node, VariableDoesNotExist
register = Library()
@register.tag(name="switch")
def do_switch(parser, token):
"""
The ``{% switch %}`` tag compares a variable against one or more values in
``{% case %}`` tags, and outputs the contents of the matching block. An
optional ``{% else %}`` tag sets off the default output if no matches
could be found::
{% switch result_count %}
{% case 0 %}
There are no search results.
{% case 1 %}
There is one search result.
{% else %}
Jackpot! Your search found {{ result_count }} results.
{% endswitch %}
Each ``{% case %}`` tag can take multiple values to compare the variable
against::
{% switch username %}
{% case "Jim" "Bob" "Joe" %}
Me old mate {{ username }}! How ya doin?
{% else %}
Hello {{ username }}
{% endswitch %}
"""
bits = token.contents.split()
tag_name = bits[0]
if len(bits) != 2:
raise template.TemplateSyntaxError("'%s' tag requires one argument" % tag_name)
variable = parser.compile_filter(bits[1])
class BlockTagList(object):
# This is a bit of a hack, as it embeds knowledge of the behaviour
# of Parser.parse() relating to the "parse_until" argument.
def __init__(self, *names):
self.names = set(names)
def __contains__(self, token_contents):
name = token_contents.split()[0]
return name in self.names
# Skip over everything before the first {% case %} tag
parser.parse(BlockTagList('case', 'endswitch'))
cases = []
token = parser.next_token()
got_case = False
got_else = False
while token.contents != 'endswitch':
nodelist = parser.parse(BlockTagList('case', 'else', 'endswitch'))
if got_else:
raise template.TemplateSyntaxError("'else' must be last tag in '%s'." % tag_name)
contents = token.contents.split()
token_name, token_args = contents[0], contents[1:]
if token_name == 'case':
tests = map(parser.compile_filter, token_args)
case = (tests, nodelist)
got_case = True
else:
# The {% else %} tag
case = (None, nodelist)
got_else = True
cases.append(case)
token = parser.next_token()
if not got_case:
raise template.TemplateSyntaxError("'%s' must have at least one 'case'." % tag_name)
return SwitchNode(variable, cases)
class SwitchNode(Node):
def __init__(self, variable, cases):
self.variable = variable
self.cases = cases
def __repr__(self):
return "<Switch node>"
def __iter__(self):
for tests, nodelist in self.cases:
for node in nodelist:
yield node
def get_nodes_by_type(self, nodetype):
nodes = []
if isinstance(self, nodetype):
nodes.append(self)
for tests, nodelist in self.cases:
nodes.extend(nodelist.get_nodes_by_type(nodetype))
return nodes
def render(self, context):
try:
value_missing = False
value = self.variable.resolve(context, True)
except VariableDoesNotExist:
no_value = True
value_missing = None
for tests, nodelist in self.cases:
if tests is None:
return nodelist.render(context)
elif not value_missing:
for test in tests:
test_value = test.resolve(context, True)
if value == test_value:
return nodelist.render(context)
else:
return ""
非常に一般的な見解では、switch文の必要性は、
。別の「例」をキャプチャし、新しいクラスやオブジェクトを作成する必要があるというサインですすると、代わりにあらゆる場所にINGの「swtich」の、あなただけのオブジェクトのメソッドを呼び出すか、オブジェクトの属性を参照して、行ってする必要があります。