3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Djangoモデルに@Propertyを使う理由と実装例

Posted at

はじめに

Djangoアプリを開発していると、「データベースには持たせないけど、テンプレートで表示したい情報」が出てくることがあります。
例えば、データベースの項目にある値同士での計算が必要なもの(進捗率や経過日数など)が挙げられます。

こうしたデータをビューやテンプレートでその都度計算すると、同じロジックをビューやテンプレートで何度も書くことになり、修正漏れや混乱を招きやすくなります。
そこで役に立つ仕組みとして、Python標準の@propertyデコレーターが便利です。

@propertyとは

Pythonの組み込み機能で、「本来なら関数として呼び出すメソッドを、変数のように扱える」仕組みです。
つまり、モデル内に計算ロジックを持たせておくことで、ビューやテンプレートからは、普通のモデルの変数(属性)のように呼び出せるようになります。
Djangoのモデルで使うと、「計算結果フィールド」を定義できるため、表示やビューの可読性を高めることが可能です。

モデルでの具体的な使い方

例えば、ToDoモデルで「進捗率」を計算する例を下記に示します。

todos/models.py
@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がテンプレートで使えるようになります。

todos/templates/todos/index.html
<p>進捗率: {{ todo.progress_percent }}%</p>

どんな場面で有効か?

  • モデルに直接DBカラムを作るほどではない、動的な計算結果を表示したいとき
  • フロント側で計算するとコードが分散するため、「表示専用のロジックはモデル側に寄せたい」とき
  • 例としては:
    • 進捗率・残日数などの算出
    • フォーマット済みの文字列化(例:苗字と名前を別カラムに入れている場合で、フルネームでテンプレートに表示させたいとき)

実務的なまとめ

  • DBに格納する必要がある値→モデルフィールド
  • 表示専用・計算結果→@propertyで定義する

まとめ

Djangoモデルにおける@propertyは、「DBには無いが計算で得られる値」を整理しておく手段です。
これにより、開発中・運用中にロジックの所在が分かりやすくなり、将来的な改修時にも役立ちます。

3
4
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
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?