django-model-utilsをいろいろ試してみる その1 StatusModel

django-model-utilsというライブラリを知りました。

その名の通りdjangoのモデルを作成するのにいろいろ便利な機能を持ってるようです。

ちょっとずつ試してみようと思います。

まずはStatusModel。


モデルがなんらかのステータスを持つのはとてもよくあることですが、その辺でなんかラクをしようというものだと予想。

モデルを作ってみます。

from model_utils import Choices
from model_utils.models import StatusModel


class Book(StatusModel):
    STATUS = Choices('new', 'reading', 'finished')
    #STATUS = Choices(('new', _('new')), ('reading', _('reading')), ('finished', _('finished')))
    #STATUS = Choices((0, 'new', _('new')), (1, 'reading', _('reading')), (2, 'finished', _('finished')))
    title = models.CharField(max_length=100)


STATUSというクラス属性を持ってるとそれが、statusというフィールドに使用されます。
上記の例だとmodels_utilsのChoicesを使ってますが、普通の要素数2のタプルでもいいようです。

また3種のSTATUSを書いて2つコメントアウトしてありますが、Chiocesの引数に単純に値を並べる方法、要素数2のタプルを使う方法、要素数3のタプルを使う方法があります。

第一の方法だと、文字列がそのまま、dbに保存する値として、また表示する値(human-readable)として使われます。
素数2の方法だと、1つめがdbに保存する値として、2つめが表示する値(human-readable)として使われます。
素数3の方法だと、1つめがdbに保存する値として、2つめがコード上の識別子として、3つめが表示する値(human-readable)として使われます。


STATUSの左端の値がデフォルト値になります。
この機能はStatusFieldというクラスを使って、StatusModelとは独立して使用することもできます。

from books.models import *
book = Book.objects.create(title='python boook')
print book.status
# => u'new'

statusの変更が行われた場合、status_changedというDateTimeFieldに変更時刻が保存されます。
この機能はMonitorFieldというクラスを使うことで、StatusModelとは独立して使うこともできます。

print book.status_changed
# => 2013-05-07 12:58:41.291251+00:00

book.status = 'reading'
book.save()
print book.status_changed
# => 2013-05-07 13:00:51.406240+00:00


statusの各code名でquerysetを取得できるようになります
このmodel_utilsのQueryManagerというクラスを使って実現されてます。

print Book.reading.all()
# => [<Book: Book object>]

print Book.new.count()
# => 0


StatusModelはこんな感じで、StatusField、MonitorField、QueryManagerの3つの機能を組み合わせたものになります。
statusのコードでquerysetが取得できるようになるのが結構いい感じ


参考 : carljm / django-model-utils / source / ― Bitbucket