複数のマネージャーを連鎖させて、個々のマネージャーの両方の影響を受けるクエリ セットを生成することが可能かどうか (可能な場合はその方法) を考えていました。私が取り組んでいる具体的な例を説明します。
他のモデルに小さな特定の機能を提供するために使用する複数の抽象モデル クラスがあります。これらのモデルのうちの 2 つは、DeleteMixin と GlobalMixin です。
DeleteMixin は次のように定義されます。
class DeleteMixin(models.Model):
deleted = models.BooleanField(default=False)
objects = DeleteManager()
class Meta:
abstract = True
def delete(self):
self.deleted = True
self.save()
基本的に、オブジェクトを実際に削除する代わりに、疑似削除 (削除済みフラグ) を提供します。
GlobalMixin は次のように定義されています。
class GlobalMixin(models.Model):
is_global = models.BooleanField(default=True)
objects = GlobalManager()
class Meta:
abstract = True
任意のオブジェクトをグローバル オブジェクトまたはプライベート オブジェクト (公開/非公開のブログ投稿など) として定義できます。
これらには両方とも、返されるクエリセットに影響を与える独自のマネージャーがあります。私の DeleteManager はクエリセットをフィルター処理して、削除済みフラグが False に設定されている結果のみを返しますが、GlobalManager はクエリセットをフィルター処理して、グローバルとしてマークされた結果のみを返します。両方の宣言は次のとおりです。
class DeleteManager(models.Manager):
def get_query_set(self):
return super(DeleteManager, self).get_query_set().filter(deleted=False)
class GlobalManager(models.Manager):
def globals(self):
return self.get_query_set().filter(is_global=1)
望ましい機能は、モデルがこれらの抽象モデルの両方を拡張し、削除されていないグローバルな結果のみを返す機能を付与することです。4 つのインスタンスを持つモデルでテスト ケースを実行しました。SomeModel.objects.all() などの結果セットを取得しようとすると、インスタンス 1 と 3 が取得されます (削除されていない 2 つのインスタンス - すばらしい!)。SomeModel.objects.globals() を試すと、DeleteManager にグローバルがないというエラーが表示されます (これは、モデル宣言がそのようなものであると想定しています: SomeModel(DeleteMixin, GlobalMixin)。順序を逆にすると、そうではありません。エラーは発生しますが、削除されたものは除外されません)。
これと似たような状況に遭遇し、結果に至った人がいるかどうかはわかりませんでした。私の現在の考え方でそれを機能させる方法、または私が求めている機能を提供する再作業のいずれかが非常に高く評価されます. この投稿が少し長くなっていることは承知しています。さらに説明が必要な場合は、喜んで提供します。
編集:
この特定の問題に使用した最終的な解決策を以下に投稿しました。これは、Simon のカスタム QuerySetManager へのリンクに基づいています。