ざきの学習帳(旧 zackey推し )

日々の学びを書きます

【Django 3.1】ForeignKey や OneToOneField で指定した参照先モデルのマネージャを指定するには Base Manager を変更する

Django 3.11 において、複数データベースを使い分ける手段を調べていたときに Default Manager Base Manager の存在を知りました。時間が経つと存在自体忘れそうなため、自分用にメモしときます。

認識齟齬等ありましたら、コメント等いただけると幸いです。 🙏

複数データベースを利用する

複数のデータベース | Django ドキュメント | Django に記載されている通り、settings.pydefault 以外のデータベース情報を定義し、

ような方法があるのかな、と思います。

参考リソース

検証用コードが載っている記事がありました。

利用するDjangoのバージョンに注意しながら、参考にすると良さそうです。

Default Manger と Base Manager

リファレンスにDefault MangerBase Mangerの説明が記載されています。

Default Manager は object の代わりに Custom Manger を指定。
Base Manger は ForeignKey や OneToOneField で参照しているモデルで使用されるマネージャを指定...と解釈しています。

コード

リファレンスを見る限り Meta.default_manager_name Meta.base_manager_name を指定するっぽいです。

ざっくり書き起こすと、以下のようなイメージです。

from django.db import models


class GeneralUserManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(owner=False)


class User(models.Model):
    description = models.TextField()
    owner = models.BooleanField(default=False)

    objects = GeneralUserManager()  # owner=True な User が抽出される
    owner_objects = models.Manager()  # すべての User が抽出される
    class Meta:
        base_manager_name = 'owner_objects'  # PcSkill から user.description のように参照される場合、指定されたマネージャが使用される


class PcSkill(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='pc_skill')
    level = models.IntegerField()

このようなモデルやマネージャを定義しておき...

skill = PcSkill.objects.get(pk=1)
skill.user.description

skill.user.description のように関連オブジェクトを参照した際、UserMeta.base_manager_nameに指定した"owner_objects"が選択されます。

カスタムマネージャは、上記サンプルコードのようにfilterしたり、usingdb_managerを用いてデータベースの切り替えたりできます。

関連するオブジェクトから使用するマネージャをカスタムマネージャに変更したい場合は、Meta.base_manager_nameに指定すると良さそうです。

Meta.default_manager_name Meta.base_manager_name は、正しくは Option.default_manager_name Option.base_manager_nameです。
 コードで説明するため、あえて Meta と書いています。

おわり

以上です。

繰り返しになりますが、認識齟齬等ありましたら、コメントなどフィードバックいただけると助かります 🙏


  1. 本記事執筆時点では 1.11〜3.1 まで有効な設定であることを確認済です。

じぶん Release Notes ver 0.31.4

f:id:kic-yuuki:20210301220125p:plain

2021年、もう2ヶ月たったのか...(早く感じる)

先月分はこちら -> じぶん Release Notes ver 0.31.3 - ざきの学習帳(旧 zackey推し )

    • 読書中
    • 完了
  • 映画
  • ブログ(PV数)
  • Challenge Every Month
    • 2021/02の結果
      • タスク
      • 本を読む
      • 婚活
    • 2021/03の目標
      • ブログ
      • タスク
      • 開発:ブログ
      • 婚活
  • おわりと所感
続きを読む

足元・寝冷えを避けるため、シュラフを買った

買ったシュラフはこちら、安価 x 洗える x 密閉型のものです。

  • きっかけ
  • 効果
    • 仕事中
    • 就寝中
  • 感想
続きを読む

じぶん Release Notes ver 0.31.3

f:id:kic-yuuki:20210131194042p:plain

じぶんリリースノート投稿タイミング、ややフライング気味ですが、気にせず。

先月分はこちら -> じぶん Release Notes ver 0.31.2 - ざきの学習帳(旧 zackey推し )

  • 学んだこと
      • 読書中
      • 完了
  • ブログ
    • PV数
  • Challenge Every Month
    • 2020/12の結果
      • 本を読む
      • 婚活
    • 2021/02の目標
      • タスク
      • 本を読む
      • 婚活
  • おわりと所感
続きを読む

SQLアンチパターンざっと読んだ / SQLだけかと思ったらテーブル系のアンチパターンも書いてあった

良書良書と聞いていたSQLアンチパターンですが、題名からSQLに特化した内容と思い込み、今まで読んでいませんでした。

www.oreilly.co.jp

先日、本書に記載されている「とりあえずID」のアンチパターンを踏んでいることを指摘いただき、購入に至った...という経緯です。

※電子版が欲しかったため、オライリーから購入しました。

本記事には、第1部をゆっくり、他部をざっくりと読み進めた際、思ったこと等を記載します。

続きを読む