1. ホーム
  2. python

[解決済み] Django でカスタム QuerySet とカスタム Manager はいつ使い分けるべきですか?

2023-05-30 06:18:32

質問

Django では、カスタムマネージャは再利用可能なクエリロジックを整理するための素晴らしい方法です。その に関する Django のドキュメントは カスタムマネージャ が言っています。

をカスタマイズしたい理由は2つあります。 Manager をカスタマイズしたい理由は 2 つあります : 追加の Manager メソッドを追加したり、初期の QuerySet という Manager が返されます。

しかし を記述しています。 どのようにカスタム QuerySet クラスを作成する方法、そして、これらのクラスは QuerySet.as_manager() :

Manager で生成されたインスタンスは QuerySet.as_manager() は、実質的に PersonManager とほぼ同じになります。

の間でロジックを整理する方法には、多くの柔軟性があるように思えます。 Manager とカスタム QuerySet クラスがあります。いつ、一方を使用するか、他方を使用するかを決定する原則は何ですか?

どのように解決するのですか?

主に、クエリを簡単に構成できるようにするためです。一般に、クエリセットの呼び出しの連鎖の中で、既存のクエリセットに対して何らかの操作を行えるようにしたい場合は QuerySet .

例えば Image モデルがあり width , height のフィールドがあります。

class Image(models.Model):
    width = ...  # Width in pixels
    height = ... # Height in pixels

を使えば、いくつかのカスタム QuerySet メソッドを書くことができます。

class ImageQuerySet(models.QuerySet): 
    def landscapes(self):
        return self.filter(width__gte=models.F('height'))

    def portraits(self):
        return self.filter(width__lte=models.F('height'))

    def small(self):
        return self.filter(width__lte=1200)

    def large(self):
        return self.filter(width__gte=1200)

class ImageManager(models.Manager):
    def get_queryset(self):
        return ImageQuerySet(self.model, using=self._db)

で、動的なクエリセットが簡単に作れるようになりました。

Image.objects.all().portraits().small()
Image.objects.all().large().portraits()

論理的には、これらの関数は主に既存のクエリセットのモデルのパーティショニングや再定義に関係するものであるべきです。既存のquerysetを操作しない、querysetを全く返さない、あるいは、この特定のモデルを伴わない、いくつかの関連するロジックを実行しなければならないような状況では、モデルマネージャがより適していると言えるでしょう。