目次
- forループの基本形 :リスト(List)、タプル(tuple)
- forループの基本形:辞書
- forループのブロック内で参照できる特別な変数
- 注意点:デフォルト辞書は直接渡せない
- おまけ:デフォルト辞書に関する記事
djangoテンプレート内でリスト・タプル・辞書型のforループについてです。
forループの基本形 :リスト(List)、タプル(tuple)
リスト(List)、タプル(tuple)の場合の基本形は。
<table> {% for v2 in lst2 %} <tr> <td>list</td> <td>{{ v2 }}</td> </tr> {% empty %} <tr> <td>list</td> <td>中身が空です。</td> </tr> {% endfor %} </table>
です。
{% empty %}は、空の場合に何か処理したい場合に使います。
IF文をネストして空チェックとかしなくていいので、何気に便利です。
もちろん、List、tupleが空の場合(例:lst2=[]で初期化したままの場合)に何か処理をする必要がなければ、{% empty %}は省略できます。
forループの基本形:辞書
辞書の場合も同様です。
<table> {% for k,v in dic3.items %} <tr> <td>辞書</td> <td>{{ k }}==>{{ v }}</td> </tr> {% empty %} <tr> <td>辞書</td> <td>空です。</td> </tr> {% endfor %} </table>
のように、辞書をループでまわすときは、itemsを使って、キーと値を取り出します。
辞書が空の時(例 dic3={}で初期化したまま)の場合に、特別に処理する必要があれば、{% empty %}のブロックが使えるのも同じです。
ループを逆順で処理したい場合は、いずれも「{% for t1 in tpl1 reversed %}」のように、「reversed」をつけることで実現できます。
forループのブロック内で参照できる特別な変数
forループのブロック中で、以下の変数が使えます。
リスト、タプル、辞書共通です。
- forloop.counter :現在のループカウンタ番号 ( 1 から順にカウント )
- forloop.counter0 :現在のループカウンタ番号 ( 0 から順にカウント )
- forloop.revcounter :現在のループカウンタ値 ( 1 から順に、末尾からカウント)
- forloop.revcounter0 :在のループカウンタ値 ( 0 から順に、末尾からカウント)
- forloop.first :最初のループであれば True
- forloop.last :最後のループであれば True
これも何気に便利です。
例えば、以下のように使えます。
{% for v1 in lst1 %} {% if forloop.first %} <tr> <td>{{ forloop.counter0 }}</td> <td>最初のレコードです。</td> </tr> {% else %} {% if forloop.last %} <tr> <td>{{ forloop.counter0 }}</td> <td>最後のレコードです。</td> </tr> {% else %} <tr> <td>{{ forloop.counter0 }}</td> <td>{{ v1 }}</td> </tr> {% endif %} {% endif %} {% endfor %}
とりあえず、ここまでは、別に注意すべきことはありません。
注意点:デフォルト辞書は直接渡せない
今回の記事のポイントはここからです。
注意すべき点。
それは。
djangoのテンプレートでforループを回す時、組込みアルゴリズムであるデフォルト辞書(difaultdict)を直接渡せないという制約があることです。
渡せない理由はこちらに書いてあります。
一部引用してまとめると。
テンプレート内では、この順番で実行しようとします:
- 辞書検索
- 属性やメソッドの検索
- 数値のインデックス検索
その仕様の影響で「defaultdict」をそのまま渡すと「.items()」メソッドではなくデフォルト値を直接参照してしまうそうです。
なので。
例えば、views.pyの中で以下のようにカウンタにdefaultdictを使った場合。
dic4 = defaultdict(int)
dic4['C'] += 1
dic4['D'] += 1
dic4['A'] += 1
dic4['C'] += 1
これをこのまま
'dic4': dic4
みたいにdjangoテンプレートに渡すとエラーになります。
回避策としては、
'dic4': dict(dic4)
のように辞書型に明示的に変換してテンプレートに渡せばよいだけなのです。
わかってしまえば簡単な話なんですけど、自分の経験では、エラーメッセージから、その原因にたどりつくのに手間取りました。
とりあえず、こんなところで。
ではでは。
おまけ:デフォルト辞書に関する記事
デフォルト辞書については、こちらの記事でちょっと書いてます。