デフォルトマネージャについての補足
重要なところの説明が抜けていたので補足。
先にまとめ
get_query_setをオーバーライドしたマネージャを作ると地雷原になりうるので、オーバーライドしないor↑の対策を忘れないようにしましょう。
逆方向リレーションのことを考えると前者がおすすめです。
get_query_set
get_query_setは、そのManagerオブジェクトが最初に生成するQuerySetを返すメソッドです。
デフォルトだと対象モデルのすべてのオブジェクトを返す=なにもフィルタが掛かっていないQuerySetを返します。
これをオーバーライドすると、そのManager全体の挙動を変更できるので
class PublishedMyManager(models.Manager): def get_query_set(self): return super(PublishedMyManager, self).get_query_set().filter(is_deleted=False) class DeletedMyManager(models.Manager): def get_query_set(self): return super(DeletedMyManager, self).get_query_set().filter(is_deleted=True) class MyModel(models.Model): is_deleted = models.BooleanField(u"削除フラグ", default=False) user = models.ForeignKey(User, verbose_name=u"ユーザー") published = PublishedMyManager() unpublished = DeletedMyManager()
下らない例ですがこう定義すると
>>> MyModel.published.all() [is_deleted=Falseのオブジェクトすべて] >>> MyModel.unpublished.all() [is_deleted=Trueのオブジェクトすべて]
という風に
- 意味が分かりやすい
- フィルタを通し忘れて削除されてるデータを表示してしまう危険性などが減る
- フィルタ書くよりコードが短くなる
なコードが掛けていいことづくめ!
大域的な挙動を変えたい時はどんどんManager生やそうぜ!
と思っていました。
1つ目の記事にもどる
4/50