モデルのsaveが変わったよ。
Django の trunk に queryset-refactor がマージされたタイミングで、 モデルの save メソッドにも改良が加えられてたのでメモメモ。
マージ前(r7476) は save メソッド自体に実際の処理が書かれてた。
# django/db/models/base.py@213行目あたり
def save(self, raw=False):
dispatcher.send(signal=signals.pre_save, sender=self.__class__,
instance=self, raw=raw)
# 中略...
dispatcher.send(signal=signals.post_save, sender=self.__class__,
instance=self, created=(not record_exists), raw=raw)
ので、データ登録の際に何か処理を挟みたい場合、 オーバーライドして処理を追加してあげて、 良いところで親の save をコールしてあげる事で実装してた(と思う)。
class Hige(models.Model):
"""
HIGEなモデル
"""
def save(self, raw=False):
# なにか追加したい処理が入る。
super(Hige, self).save(raw=raw)
でも、これだとダイレクトにデータを保存したい場合に、 適当な名前でもうひとつ save メソッドを作ってやる必要があった。
class Hige(models.Model):
"""
HIGEなモデル
"""
def save(self, raw=False):
"""
adminとかでは処理を追加したいので、
オーバーライドせざるを得ないんだ。
"""
# なにか追加したい処理が入る。
super(Hige, self).save(raw=raw)
def direct_save(self, raw=False):
"""
たまーに処理を追加しないのも必要。
"""
super(Hige, self).save(raw=raw)
こういう状況になると、ものっすごい残念な気持ちになってた訳なのですが、 これが マージ後(r7477) でちょっと素敵に改良されてるよ。
# django/db/models/base.py@293行目あたり
def save(self):
"""
Save the current instance. Override this in a subclass if you want to
control the saving process.
"""
self.save_base()
def save_base(self, raw=False, cls=None):
"""
Does the heavy-lifting involved in saving. Subclasses shouldn't need to
override this method. It's separate from save() in order to hide the
need for overrides of save() to pass around internal-only parameters
('raw' and 'cls').
"""
# 省略...
実際のデータ登録の処理は全部 save_base メソッドで実装しておいて、 save メソッドはそのフックになってるよ。 これだと、ダイレクトにデータを登録する必要が出て来た場合でも、 save_base をコールすれば良いだけ。 なので、特にモデルに変更を加える必要は無い。
class Hige(models.Model):
"""
HIGEなモデル
"""
def save(self):
"""
処理を追加したいのでオーバーライド。
raw=Falseは無くなってるよ。
"""
# なにか追加したい処理が入る。
# self.save_base()ってしてないのはなんとなく。
super(Hige, self).save()
これでもう残念な気持ちにならなくて良いね。
また一つ、 Django が好きになりましたとさ ![]()
- Posted at:
- 2008/05/02 00:29:35
- 2 Comments
- 1 TrackBack
- Trackback:
- http://humming.via-kitchen.com/2008/05/02/changed-models-save-on-django/trackback/
TrackBacks
[Django][Google App Engine]巡回 - 常山日記
Django Snippets: QuerySetManager - easily add new QuerySet methods using a Model inner class Google Code: django-bayesianvoting Voting on objects with optional Bayesian Ranking Blog: モデルのsaveが変わったよ。 jQuery style chaining with the Django ORM Fr
- Created at:
- 2008/05/02 02:10:45
Comments
MiCHiLU
そこに処理を挟む時はSignalsを使ったりするなぁ、特に複数Modelに跨がる処理では。
nobu
>MiCHiLU
アドバイスありがとうございますー。
例えの内容が伝わりにくかったかもです。すいません。
普段は最終更新日時を自動で入れたいんだけども、
特定の場合はそうして欲しくない。的な発想でした。
大掛りな処理になるのであれば、
Signals使って分けてあげたほうが、
すっきり書けて良いですよね