はじめに
Djangoアプリを開発していると、「データベースには持たせないけど、テンプレートで表示したい情報」が出てくることがあります。
例えば、データベースの項目にある値同士での計算が必要なもの(進捗率や経過日数など)が挙げられます。
こうしたデータをビューやテンプレートでその都度計算すると、同じロジックをビューやテンプレートで何度も書くことになり、修正漏れや混乱を招きやすくなります。
そこで役に立つ仕組みとして、Python標準の@property
デコレーターが便利です。
@property
とは
Pythonの組み込み機能で、「本来なら関数として呼び出すメソッドを、変数のように扱える」仕組みです。
つまり、モデル内に計算ロジックを持たせておくことで、ビューやテンプレートからは、普通のモデルの変数(属性)のように呼び出せるようになります。
Djangoのモデルで使うと、「計算結果フィールド」を定義できるため、表示やビューの可読性を高めることが可能です。
モデルでの具体的な使い方
例えば、ToDoモデルで「進捗率」を計算する例を下記に示します。
@property
def progress_percent(self):
actual = self.actual_value # 実績値
target = self.target_value # 目標値
# 実績値はNoneでないこと、目標値はNone及び0でないこと
# 念のため例外をキャッチ
if actual is not None and target is not None and target != 0:
try:
# 実績値/目標値で進捗率を出している
return int((actual / target) * 100)
except ZeroDivisionError:
return 0
return None
テンプレートでの使い方
Djangoテンプレートでは、通常のフィールドのように使えます。
上記で設定したprogress_percent
がテンプレートで使えるようになります。
<p>進捗率: {{ todo.progress_percent }}%</p>
どんな場面で有効か?
- モデルに直接DBカラムを作るほどではない、動的な計算結果を表示したいとき
- フロント側で計算するとコードが分散するため、「表示専用のロジックはモデル側に寄せたい」とき
- 例としては:
- 進捗率・残日数などの算出
- フォーマット済みの文字列化(例:苗字と名前を別カラムに入れている場合で、フルネームでテンプレートに表示させたいとき)
実務的なまとめ
- DBに格納する必要がある値→モデルフィールド
- 表示専用・計算結果→
@property
で定義する
まとめ
Djangoモデルにおける@property
は、「DBには無いが計算で得られる値」を整理しておく手段です。
これにより、開発中・運用中にロジックの所在が分かりやすくなり、将来的な改修時にも役立ちます。