2

次のことを考慮して、多対多フィールドのモデルマネージャーをオーバーライドするにはどうすればよいですか:

class TermsManager(models.Manager):
    def all(self):
        return super(TermsManager, self).all().filter(condition_here)


class Term(models.Model):
    objects = TermsManager()

    name = models.CharField(max_length=255)

class Object(models.Model):        
    title = models.CharField(max_length=255)
    terms = models.ManyToManyField(Term, blank=True)

class Channel(Object):
    class Meta:
        proxy = True

ChannelTermManager という TermManager を継承するクラスもあります。mychannel.terms が TermManager の代わりに ChannelTermManager を呼び出すように、Channel モデルの「terms」フィールドをオーバーライドするにはどうすればよいですか?

4

1 に答える 1

3

まず第一に、オーバーライドすべきではありませんall()get_query_setデフォルトのクエリセットを変更する場合は、次のようにオーバーライドします。

class TermsManager(models.Manager):
    def get_query_set(self):
        return super(TermsManager, self).get_query_set().filter(condition_here)

これは、他のクエリセット関数がチェーンされている場合に省略されることが多く、明示的に呼び出されall()たかどうかにかかわらず、クエリセットが同じように動作するようにするためです。all()

しかし、それでも、あなたがしていることにはまだ問題があります。manager のドキュメントで説明されているように、デフォルトの関連クエリセットをフィルタリングすると、舞台裏であらゆる種類の自動処理に影響します (データをダンプしてバックアップ/フィクスチャを作成するときなど)。 ほとんどの場合、これは必要ありませんuse_for_related_fields = Trueまた、古いデータを単に検出してアラートを作成したり、クリーンアップするものを作成したりするのではなく、データベースに実際に保存されているものをマスクするため 、関連するオブジェクトマネージャーがこれを (設定することにより) 行うことは本当に望ましくありません。use_for_related_fieldsフィルタリングではなく、通常のマネージャーの通常の機能を拡張するマネージャーを作成することを目的としています。

ただし、私はあなたと同様の状況にあり、次のように処理しました。

class FilteredTermsManager(models.Manager):
    def get_query_set(self):
        return super(TermsManager, self).get_query_set().filter(condition_here)

class Term(models.Model):
    allTerms = models.Manger() # Establish this as the default/automatic manager
    objects = FilteredTermsManager()

    name = models.CharField(max_length=255)

このようにして、フィルタリングされたクエリセットを介してモデルに対するすべての最初のクエリを実行でき、「通常の Django」のように見えますが、すべてのリレーショナルおよび舞台裏のクエリは、フィルタリングされていないデータベースで機能します。そして、手動でTerm.allTerms.all().

さまざまな関連オブジェクトにさまざまなマネージャーを使用することに関しては、実際にできることは何もありません。しかし、特定のオブジェクトをカスタム マネージャーに追加して、 get querysets fromChannelで動作するメソッドからそれらを呼び出さないのはなぜでしょうか?TermObject

于 2012-11-28T22:25:29.730 に答える