• 2018-06-25
ウズマスター戦記
ウズマスター戦記 https://www.uzumax.org/2018/06/djangofor.html

Djangoテンプレートのループタグ「for」のまとめ

Djangoのテンプレート側でリストをループするタグ「for」についてです。
大概のライブラリにはループ、イテレーション機能はついているものですが、Djangoのforは機能も豊富なのでまとめてみました。


基本編:普通にfor出力

とりあえず、細かい要素は抜きで普通に表示してみましょう。

view.py

viewからテンプレートに対しリストを流し込みます。
def tagfor(request):
    context = {}
    list = []
    list.append({"name": "一郎", "age": 30})
    list.append({"name": "次郎", "age": 32})
    list.append({"name": "三郎", "age": 31})

    context["person_list"] = list

    return render(request, 'tag_samples/tagfor.html', context)

tagfor.html

リストの中身をループして表示するforタグの記述はこちら。
    {% if person_list %}
    <table class="table table-striped table-bordered">
        <thead>
        <tr>
            <td>名前</td>
            <td>年齢</td>
        </tr>
        </thead>
        <tbody>
        {% for person in person_list %}
        <tr>
            <td>{{ person.name }}</td>
            <td>{{ person.age }}</td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
    {% endif %}

結果

無事にループ表示が出来ました。



発展編:各種ループ変数

Djangoのforタグにはループカウンターなどを簡単に取得出来るよう、変数が用意されています。便利です。

変数 効果
orloop.counter 1から順に数えたカウンター
forloop.counter0 0から順に数えたカウンター
forloop.revcounte 末尾から順に、1から数えたカウンター
forloop.revcounter0 末尾から順に、0から数えたカウンター
forloop.first ループの最初の時にTrue、それ以外はFalse
forloop.last ループの最後の時にTrue、それ以外はFalse
forloop.parentloop 入れ子ループの時に、その親のループを指定

このうち、forloop.parentloop以外の出力方法はこちら。そのままです。

tagfor.html

    <table class="table table-striped table-bordered">
        <thead>
        <tr>
            <td>forloop.counter</td>
            <td>forloop.counter0</td>
            <td>forloop.revcounter</td>
            <td>forloop.revcounter0</td>
            <td>forloop.first</td>
            <td>forloop.last</td>
            <td>名前</td>
            <td>年齢</td>
        </tr>
        </thead>
        <tbody>
        {% for person in person_list %}
        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ forloop.counter0 }}</td>
            <td>{{ forloop.revcounter }}</td>
            <td>{{ forloop.revcounter0 }}</td>
            <td>{{ forloop.first }}</td>
            <td>{{ forloop.last }}</td>
            <td>{{ person.name }}</td>
            <td>{{ person.age }}</td>
        </tr>
        {% endfor %}
        </tbody>
    </table>

結果



親を取得するループ変数「forloop.parentloop」

forloop.parentloopはちょっと変わってますね。
listの中にlistが入っている構成になっている場合、一つ上の親を取るというテクニカルな変数です。

view.py

viewからテンプレートに対し入れ子構成のリストを流し込みます。
def tagfor(request):
    context = {}
    list = []
    list.append({"name": "一郎", "age": 30})
    list.append({"name": "次郎", "age": 32})
    list.append({"name": "三郎", "age": 31})

    context["person_list"] = list

    parent_list = []
    parent_list.append(list)
    parent_list.append(list)
    parent_list.append(list)

    context["parent_list"] = parent_list

    return render(request, 'tag_samples/tagfor.html', context)

tagfor.html

{{ forloop.parentloop.counter }}という感じに、親を指定してからその中身のパラメータを取得出来ます。
    <table class="table table-striped table-bordered">
        <thead>
        <tr>
            <td>親番号</td>
            <td>名前</td>
            <td>年齢</td>
        </tr>
        </thead>
        <tbody>
        {% for person_lists in parent_list %}
        {% for person in person_list %}
        <tr>
            <td>{{ forloop.parentloop.counter }}</td>
            <td>{{ person.name }}</td>
            <td>{{ person.age }}</td>
        </tr>
        {% endfor %}
        {% endfor %}
        </tbody>
    </table>

結果



リストが無い場合の挙動「for ... empty」

こんなものがあるのか。。。
テンプレート側でリストに値がある/ないを判断するにはifタグを使用すれば良いですが、forタグを組み合わせて使用する時に限り「for ... empty」が使えるそうです。

ifタグでやるのと結果は同じですが、こっちを使う方が簡潔に記述出来たり、処理速度を速くしたり出来るそうなので、出来るだけこっちを使う方が良いでしょう。

tagfor.html

    <table class="table table-striped table-bordered">
        <thead>
        <tr>
            <td>名前</td>
            <td>年齢</td>
        </tr>
        </thead>
        <tbody>
        {% for empty in empty_list %}
        <tr>
            <td>{{ empty.name }}</td>
            <td>{{ empty.age }}</td>
        </tr>
        {% empty %}
        <tr>
            <td colspan="2">表示対象がありません。</td>
        </tr>
        {% endfor %}
        </tbody>
    </table>

結果




変数とかemptyとかの機能は自分で作ることも簡単ですが、元々備わっている機能を自分でまた作るのは何も良いことありません。

存在する機能は積極的に使っていきたいものですね。

出展

公式サイトはこちら。


バックナンバー

0 件のコメント:

コメントを投稿

お気軽にコメント下さい。