1
2

More than 3 years have passed since last update.

Djangoのみでテーブル作成してみた

Posted at

Background

表示側に配列で複数の要素を受け取って、そこから <table></table> 使って表示させたい場合です。
5段列で表示させたいとなった場合はどこかで列分の割り算をする場面が出てきます。

javascriptであれば、

    var i = 0;
    var cols = 5; //列数
    var row_ele = NaN;

    for (key in dataset){
        if (i == 0){
            row_ele = NaN;
            row_ele = $("<tr></tr>");
        } 

        var cell = $("<td></td>");
        cell.text(dataset[key]);
        row_ele.append(cell);

        if (i == cols - 1){
            i = 0;
            $("table").append(row_ele);
        } else {
            i++;
        }
    }

と書けそうです。

ですが、標準のDjangoではtemplate内では計算はできません。
ここでは、django-mathfiltersモジュールを紹介しつつ、計算方法を書いてみます。

dataset & list view

サンプル例として、twitterでトレンドに上がったワード約100件分を使っています。

views.py
from django.views.generic import TemplateView

class IndexView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        words = ['全面停止','#彼氏と彼女の身長差は13cmがベスト','仕事始め','板野友美','ともちん結婚'
                ,'外国人の新規入国','ビジネス関係者','#解決KingandPrince','#スッキリ','#あさイチ'
                ,'鬼滅声優','リモート生出演','学徒動員','#おちょやん','満員電車'
                ,'小池氏の失政','仕事初め','大学院生','教員の医療現場','看護系大学'
                ,'浪川さん','いちごの日','完全勝利S','高津監督','宣言発令要請'
                ,'浅沼さん','婚姻届証人欄','秋元康氏','千代ちゃん','中山1R'
                ,'刀剣男士めし','奎二くん','豊洲市場','仕事はじめ','ミノタウロスの皿'
                ,'寒の入り','高校サッカー緊急事態宣言','囲碁の日','イングランド','新人部門'
                ,'イチゴの日','不法就労・ギャラ無申告','まんばちゃん','静岡開催','旭川医大学長発言'
                ,'テレワーク','ウーマンラッシュアワー村本','すしざんまい','埼玉自粛','大間産本マグロ'
                ,'鬼滅声優','仕事初め','大学院生','教員の医療現場','いちごの日'
                ,'看護系大学','浪川さん','完全勝利S','宣言発令要請','高津監督'
                ,'婚姻届証人欄','秋元康氏','浅沼さん','千代ちゃん','奎二くん'
                ,'刀剣男士めし','豊洲市場','仕事はじめ','ミノタウロスの皿','イングランド'
                ,'囲碁の日','寒の入り','まんばちゃん','新人部門','イチゴの日'
                ,'高校サッカー緊急事態宣言','旭川医大学長発言','静岡開催','大間産本マグロ'
                ,'埼玉自粛','テレワーク','すしざんまい','板野さん','不法就労・ギャラ無申告'
                ,'はまっする','全面停止','仕事始め','#彼氏と彼女の身長差は13cmがベスト','板野友美'
                ,'ともちん結婚','外国人の新規入国','ビジネス関係者','#解決KingandPrince','#おちょやん'
                ,'#スッキリ','#あさイチ','リモート生出演','小池氏の失政','学徒動員'
                ,'満員電車']
        context["tweets"] = words 
        return context
index.html
<!DOCTYPE HTML>

<html>
    <head> </head>
    <body> 
        <h1> mathfilter </h1>
            <ul>
            {% for item in tweets %}
                <li>{{item}}</li>
            {% endfor %}
            </ul>
    </body>
</html>

tweetsをキーとしてツイートワードが入っている配列を格納して、view側に送っていて、{% for item in tweets %}{% endfor %} でfor文を使って各要素を描画しています。

表示は一列のリスト表示になります。

add module

次にdjango-mathfilters を追加します。モジュールをpipでインストールをして、settings.pyでアプリケーションを追加します。

pip3 install django-mathfilters
settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'mathfilters'
]

improvement

<!DOCTYPE HTML>
{% load mathfilters %} <!-- html内で定義 -->

<html>
    <head> </head>
    <body> 
        <h1> mathfilter </h1>
            <table>
            {% for item in tweets %}
                {% with index=forloop.counter0 %} <!-- index を取得 -->
                    {% if index|mod:5 == 0 %} <tr> {% endif %}
                        <td>
                            {{item}}
                        </td>
                    {% if index|mod:5 == 4 %} </tr> {% endif %}
                {% endwith %}
            {% endfor %}
            </table>
    </body>
</html>

{% with index=forloop.counter0 %}{% endwith %} とすると for i, item in enumerate(range(...)): print(i)みたいにインデックスの取得ができます。この機能はDjangoの標準にあります。
index|mod:5 が 今回紹介したいmathfiltersの機能で数字の余りを算出してくれます。この他にもaddition sub mul div をつけると四則演算ができます。
ここではindex % 5 == 0だったら先頭に<tr>をつけ、index % 5 == 4であれば最後尾に</tr>をつける実装をしています。

ブラウザは以下の通りにテーブルの5段列で表示されます。
capture.png

Reference

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2