見出し画像

Django_modelのManagerをオーバーライドしてカスタムする #430

Djangoのmodelで特殊な操作を実行するため、Managerをオーバーライドしてカスタムすることがあると思います。

しかしこのManagerにも2種類あって、使い分けなどややこしかったので違いを整理してみました。

以下の2つです。
・Djangoのmodels.Manager
・外部ライブラリdjango_mysqlのQuerySet

Djangoのmodels.Manager

Djangoにデフォルトで装備されているクラスで、これをオーバーライドすることでカスタムな処理を定義できます。

データベースに対する基本的なCRUD操作をサポートしていますし、何より公式のものなので安心感があります。

異なるデータベースバックエンドでの移植性を重視して設計されているようで、将来的にデータベースを変更する可能性がある場合などは一層適しています。

公式のサンプルコードです。

# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(author='Roald Dahl')

# Then hook it into the Book model explicitly.
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = models.Manager() # The default manager.
    dahl_objects = DahlBookManager() # The Dahl-specific manager.

ここではobjectsと分けて実装されていますが、objectsをカスタムManagerに指定することもできます。

この例だと、以下のように書くとauthorがRoald dahlのデータだけgetされます。

Book.dahl_objects.all()


django_mysqlのQuerySet

MySQL固有のクエリや関数をサポートします。MySQLの特定のバージョンや機能に依存する場合があるため、他のデータベースエンジンでの使用は推奨されません。

以下のような、MySQL固有のクエリや関数をサポートします。

フルテキスト検索

MySQLのFULLTEXTインデックスを活用して、テキスト検索を高速化するためのサポート。

Approximate COUNT

大規模なテーブルに対して高速な近似的なレコードカウントを提供。

Database Functions

MySQL固有のデータベース関数をサポート。例:BIT_LENGTH, CAST, CONCAT_WS など。

サンプルコードです。

from django_mysql.models import QuerySet
 
class _QuerySet(QuerySet):
  def active(self):
    return self.filter(deleted_at=None)
 

class TestCampaign(models.Model):
  objects = _QuerySet.as_manager()
  name = models.CharField(max_length=255)
  created_at = models.DateTimeField(auto_now_add=True)
  updated_at = models.DateTimeField(auto_now=True)
  deleted_at = models.DateTimeField(null=True)

ここでは以下のように記述すると、deleted_atがnull(=論理削除されていない)のデータが抽出されます。

test_campaings = TestCampaign.active()


2つの使い分け

django_mysqlはMySQL特有の機能を活用することを前提としています。そのため、MySQLの特定の高度な機能や最適化を利用したい場合はこちらを選ぶのが良いと言えます。

ただ通常利用の範囲に収まるのであれば、MySQLであっても、公式にサポートされているDjangoデフォルトのManagerが良いのではないかと個人的には思いました。


ここまでお読みいただきありがとうございました!

参考


いいなと思ったら応援しよう!