"BOKU"のITな日常

62歳・文系システムエンジニアの”BOKU”は日々勉強を楽しんでます

djangoテンプレート内ので条件分岐(IF文)で複数条件を指定するときに注意すること

djangoテンプレート内で{% if %}で条件分岐するやり方と注意点についてまとめます。

f:id:arakan_no_boku:20191230001930p:plain

 

IF構文の基本パターン

 

djangoテンプレート内で使える条件分岐の基本形は。

{% if  ..... %}
  ・・・・
{% elif  ...... %}
  ・・・・
{% else %}
  ・・・・
{% endif %} 

 です。

elifは何回でも繰り返し使えます。

利用できる演算子は。

演算子 用途
== 値が等しい場合にTrue。文字列・数字他 {% if somevar == "x" %}
 != 値が等しくない場合にTrue。文字列・数字他 {% if somevar != "x" %}
 < より小さい場合にTrue {% if somevar < 100 %}
 > より大きい場合にTrue {% if somevar > 100 %}
 <= 以下(より小さい又は等しい)場合にTrue {% if somevar <= 100 %}
 >= 以上(より大きい又は等しい)場合にTrue {% if somevar >= 100 %}
 in 指定の値が存在する場合にTrue。 {% if "bc" in "abcdef" %}/{% if "hello" in wordlist %}
 not in 指定の値が存在しない場合にTrue {% if "bc" not in "abcdef" %}/{% if "hello" not in wordlist %}
 is 2つの値が同じオブジェクトの場合にTrue {% if somevar is True %}/{% if somevar is None %}
is not 2つの値が同じオブジェクトでないとTrue {% if somevar is not True %}/{% if somevar is not None %}

 などです。

文字列やコンテナ型(List、tuple、Dictなど)については、

{%  testlist  %}

または

{%  not testlist  %}

のように直接条件文にいれて、True( 変数が存在し、空ではなく、その値が Falseでない)か、not Trueかで分岐できます。

条件分岐の例を以下に書きますが、これも至って普通です。

Views.py等で「'kanji1': kanji」で変数「kanji」に格納した文字列で条件分岐するような場合です。、

{% if not kanji1 %}
	<tr>
		<td>文字列が空です</td>
		<td>{{ kanji }}</td>
	</tr>
{% elif '漢字' in kanji1 %}
   	<tr>
		<td>文字列に漢字が含まれる</td>
		<td>{{ kanji1 }}</td>
	</tr>
{% else %}
   	<tr>
		<td>いずれでもない</td>
		<td>{{ kanji1 }}</td>
	</tr>
{% endif %}

 

ちょっと注意しないといけないと思っていること

 

ここまでは至って普通です。

でも、ちょっとだけ注意が必要なことが2点あります。

それは。

  • {% if ・・・ %}の中で丸括弧「()」が使えないこと。
  • django側で条件を暗黙的にグループ化するルールに癖があること

です。

条件式に丸括弧「()」を使うとエラーになります。

複数の条件を組み合わせる必要がある時に丸括弧「()」でくくれません。

しかも。

カッコを使わないで複数条件を並べて書いた時には、django側が暗黙的に優先度の規則に従って、グループ化するのですが、そこにちょっとクセがあります。

その例を、以下のトキュメントから拾うと、

docs.djangoproject.com

こんなことが書いてある部分があります。

and と or は同じタグの中で同時に使用できます。

このとき優先順位は and が優先します:

つまり

{% if a == 1 and b == 2 or c == 3 %}

と書くと

暗黙的い「if (a == 1 and b == 2) or c == 3」と解釈されるということです。

もし、「if (a == 1 and (b == 2 or c == 3)」と評価させたい場合は、以下のようにネストして書く必要があります。

{%  if  a == 1 %}

     {% if  b == 2 or c == 3 %}

ところが。

その少し下の方で「演算子の優先順位」のところには、 

優先順位の規則を理解することが重要です。

演算子の優先順位は次のようになっています:

  • or
  • and
  • not
  • in
  • ==, !=, <, >, <=, >=

 と書かれていて、その例として。

{% if a == b or c == d and e %}
 ...次のように解釈されます:

(a == b) or ((c == d) and e)

 と書かれていたりします。

実にややこしいです。

よーっく考えればわかるのでしょうが。

パッとみると、一瞬、「or」と「and」が逆転しているように見えて混乱します。

これがバグの元になりやすいと、自分が考える「クセ」です。

 

だから。

若干不細工でも、andとorが混在する場合は、IFタグをネストさせて書くほうが良い。

そう・・個人的には思っています。

ではでは。