te-touのブログ

音楽制作・車・プログラミング・旅行・その他考えてる事など、備忘録的なことも含めて個人的なページです。

Django ListViewで2つ以上の小数点を持つフィールドの計算結果を求める。(テンプレートタグ)





Djangoのテンプレートで四則演算を行うときの方法です。
単純にテンプレート上でA+Bみたいなことが出来なかったので調べました。

整数の計算であれば、前回の記事で書いた「項目1|add:項目2」のように書けば足し算してくれます。
www.te-tou.tokyo
しかし、小数点の計算計算は出来ません。

まさか四則演算でハマるとは思ってもいませんでしたが、これを実現するために関数を使う必要があるようです。
なので、「テンプレートタグ」というものを使います。

テンプレートフィルタとテンプレートタグの違い

ざくっと受けられる引数に違いがあるようです。

  • テンプレートフィルタ(引数2つまで)
  • テンプレートタグ(引数2つ以上使用可能)

今回は引数を2つ以上使いたいので、テンプレートタグを使用します。

環境
  • python : 3系
  • Django : version 3.0.2
用例

scoreというアプリがあるとします。テスト点数を入力してゆくアプリです。
そしてその入力したテストの点数の合計値をListViewで表示させます。
英語とかの点数に小数点はなかなかないとは思いますが、細かいことは考えず。
modelsの「scoreテーブル」に以下のフィールドを持っている。

  • 名前
  • 英語得点
  • 国語得点
  • 数学得点
  • 理科得点
  • 社会得点

ListViewで「英・国・数・理・社」の合計点数を表示する。

関数を作る(テンプレートタグ)

まず、templatetagsというフォルダをtemplatesと同じ階層に作成します。
そのフォルダの中にテンプレートタグ(関数)ファイルを作成します。
名前はなんでも良いので、sum_points.pyとします。
省略
┗score
 ┗templates
 ┗templatetags ←フォルダを作る。
  ┗sum_points.py ←テンプレートタグファイルを作成する。

sum_points.pyの中身

from django import template
#テンプレートライブラリに登録する
register = template.Library()
@register.simple_tag

#関数名はpoints
#引数5つを受け取り、足し算した結果を返り値へ送る
def points(value1, value2, value3, value4, value5):
    return value1 + value2 + value3 + value4 + value5
ソース

models

from django.db import model

class Score(models.Model)
          name = models.CharField(
                 verbose_name = '名',    
                 max_length=10,
           )
           #得点はフロート型で小数点以下を入力可能とする。
           engPoint = models.FloatField(
                 verbose_name='英語',
                 default=0.0
           )
           natPoint = models.FloatField(
                 verbose_name='国語',
                 default=0.0
           )
           matPoint = models.FloatField(
                 verbose_name='数学',
                 default=0.0
           )
           sciPoint = models.FloatField(
                 verbose_name='理科',
                 default=0.0
           )
           socPoint = models.FloatField(
                 verbose_name='社会',
                 default=0.0
           )

views

from django.shortcuts import render

class ScoreListView(ListView):
          model = Score,
          template_name = 'score/score_list.html'  #使用するテンプレートを指定

urls

from django.contrib import admin
from django.urls import path

from name.views import ScoreListView

urlpatterns = [
          path('score', ScoreListView.as_view(), name="score"),
          path('admin/', admin.site.urls),

いつも通りパスを通して。

template (score_list.html)

<div>
    {% for score in object_list %}
    <tr>
        <!-- リストの一番左にNoをカウントアップして自動的につける -->
        <td>{{ forloop.counter }}</td>

        <td>{{ score.name }}</td>

        <!-- 英国数理社の得点を入力 -->
        <td>{{ score.engPoint }}</td>
        <td>{{ score.natPoint }}</td>
        <td>{{ score.matPoint }}</td>
        <td>{{ score.sciPoint }}</td>
        <td>{{ score.socPoint }}</td>

        <!--  合計得点を表示する -->
        {% points score.engPoint score.natPoint score.matPoint score.sciPoint score.socPoint %}
        <!--  関数名・引数1・引数2・引数3・引数4・引数5 を書くと、結果が返り値として表示される -->
    </tr>
    {%  endfor %}
</div>
まとめ

これで同一レコードの四則演算が出来ます。
querysetだとテーブルに対してフィルタとかかけるような感じなので、用途が違いますね。もしかしたら、querysetとかでもっと賢い方法があるかもしれませんが。




www.facebook.com
www.youtube.com