自動化無しに生活無し

WEBとかAIとかLinux関係をひたすら書く備忘録系ブログ

Djangoのモデルに独自メソッドを追加、テンプレートに表示【フィールド間の計算、他モデルの値の表示などに有効】

thumbnail

モデルにメソッドを追加することで、テンプレート側から属性値として参照することができる。

from django.db import models

class Topic(models.Model):

    comment     = models.CharField(verbose_name="コメント",max_length=2000)
    time        = models.IntegerField(verbose_name="活動時間(分)",default=0)
    level       = models.IntegerField(verbose_name="負荷レベル",default=0)

    def score(self):
        return self.time*self.level

    def __str__(self):
        return self.comment

テンプレートからこのモデルオブジェクトの.scoreを参照すると、計算結果が出力される。

{{ topic.score }}

間違っても下記のように書かないように。当然だが、フィールド名の重複にも注意。後書き有利。

from django.db import models

class Topic(models.Model):

    comment     = models.CharField(verbose_name="コメント",max_length=2000)
    time        = models.IntegerField(verbose_name="活動時間(分)",default=0)
    level       = models.IntegerField(verbose_name="負荷レベル",default=0)

    #後続のscoreメソッドにより上書きされるためこれは意味ない。
    #score       = models.IntegerField(verbose_name="負荷レベル",default=0)

    """ 
    #これらは動かない。
    #score       = time*level
    #score       = self.time*self.level
    """ 

    def score(self):
        return self.time*self.level


    def __str__(self):
        return self.comment

別のモデルクラスの値を参照する。

例えば、通知のモデルクラスと、ユーザーのモデルクラスが、多対1で繋がっている場合、通知の総数を知りたい時は下記のように記述すれば良い。

#========省略===========

from tube.models import NotifyTarget


#ここ( https://github.com/django/django/blob/master/django/contrib/auth/models.py#L321 )から流用
class CustomUser(AbstractBaseUser, PermissionsMixin):

    #========省略===========

    #通知の数をカウントして返却する。
    def notify_num(self):
        return NotifyTarget.objects.filter(user=self.id,read=False).count()

これで、ユーザーモデルのオブジェクトは

{{ request.user.notify_num }}

などとして通知の総数を確認することができる。

ユーザーモデルは常に返却されるrequestオブジェクトから参照できるため、ビュー側で検索の処理をしなくてもいい。ヘッダーなど常に表示される箇所はこのようにして簡単に表示できるので、ビューの処理の大幅な削減が期待できる。

ただし、カスタムユーザーモデルなど、通常のモデルとファイルが分離されている状況にある場合、importする側される側の関係を考慮しなければ動作しない。

結論

フィールド間の計算、他モデルの参照などはこれで実現できる。毎度毎度モデルオブジェクトを作るたびにビュー側で参照しているようではコードが長くなるので、これは有効に活用したいところだ。

当然ではあるが、saveとdeleteは既に使われているメソッドであるため、上書きしてはならない。

スポンサーリンク

シェアボタン

Twitter LINEで送る Facebook はてなブログ