Djangoでお手軽に論理削除(Logical Deletion)を実装する

Djangoのモデルにお手軽に論理削除の機能を追加するライブラリのご紹介

Django-Boost

Django-Boost https://github.com/ChanTsune/django-boost

今回、論理削除を実装するにあたって利用するライブラリです。
論理削除の機能以外にもDjangoで開発を行うときに便利な関数、ミックスインクラス群が纏ったパッケージです。

導入

pipを使ってインストールできます。

pip install django_boost

settings.pyファイルのINSTALLED_APPSの項目に"django_boost"を追加します。

INSTALLED_APPS = [
    "django_boost",
]

論理削除に対応したモデルを作成する

論理削除に対応したモデルを作成するには、LogicalDeletionMixinクラスを利用します。

from django.db import models
from django_boost.models.mixins import LogicalDeletionMixin

class MyModel(LogicalDeletionMixin):
    field_1 = models.TextField()

論理削除の機能を持たせたいモデルにLogicalDeletionMixinを継承させます。

これだけでモデルクラスを論理削除に対応させることが出来ます。

名前にMixinとついていますが、LogicalDeletionMixinクラスは既にModelクラスを継承しているため、改めてModelクラスを継承させなくてもそのまま使えます。

LogicalDeletionMixinを継承したクラスは、deleted_atという名前のDateTimeFieldを持つようになります。
このフィールドには、論理削除された日付が入ります。
削除されていない(データが生きている)場合は、nullが入っています。

また、クエリーセットやマネージャクラスも論理削除の機能に対応したLogicalDeletionQuerySet, LogicalDeletionManagerに置き換わります。

なので、クエリーセットやマネージャクラスをカスタムしたい場合は、それぞれdjango_boost.models.query.LogicalDeletionQuerySet, django_boost.models.manager.LogicalDeletionManagerを継承することをお勧めします。

論理削除(soft delete)する

LogicalDeletionMixinを継承したモデルクラスは、deleteメソッドの呼び出しが論理削除に置き換わります。

object = MyModel.object.get(id=1)
object.delete() # <- 論理削除

物理削除(hard delete)する

deleteメソッドにhard=Trueの引数を渡すことで物理削除を実行できます。

object = MyModel.objects.get(id=1)
object.delete(hard=True) # <- 物理削除

複数データをまとめて論理削除する

論理削除されていないデータを取得する

論理削除されていないデータ(生きているデータだけ)を取得するにはaliveメソッドが利用できます。

queryset = MyModel.objects.alive() # 論理削除されていないデータのみを取得

deleted_atフィールドの値がnullのデータをフィルタリングして取得しています。

論理削除されたデータを取得する

論理削除されたデータのみを取得するにはdeadメソッドが利用できます。

queryset = MyModel.objects.dead() # 論理削除されたデータのみを取得

deleted_atフィールドの値がnullではないデータをフィルタリングして取得しています。

論理削除されているデータも含めて取得する

論理削除されたデータも含めて全てのデータを取得する場合は、通常のクエリーセットの操作同様、allメソッドを利用します。

queryset = MyModel.objects.all() # 全てのデータを取得

Admin画面から扱う

DjangoのAdminページに論理削除に対応したモデルを登録するときに、LogicalDeletionModelAdminクラスを利用すると、論理削除されたデータ、されていないデータを切り替えて表示できるフィルター機能が有効になります。

from django.contrib import admin
from django_boost.admin import LogicalDeletionModelAdmin

from .models import MyModel

@admin.register(MyModel)
class MyModelAdmin(LogicalDeletionModelAdmin):
    pass

最後に

以上、Djangoのモデルクラスにお手軽に論理削除の機能を実装するライブラリDjango-Boostのご紹介でした。

論理削除に関連する機能に追加の要望等があれば、どんどんissueを立ててください!
また、PR等もお待ちしております!