28
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Djangoで作成日時と更新日時、論理削除を設定

Last updated at Posted at 2019-01-08

最新情報

最新のDjangoで作成日時と更新日時、論理削除を設定は

すぐに使える❗ Djangoに論理削除を導入

に改めて書きました。

環境

  • django2.1

ベースモデル

ここで、作成日時と更新日時と削除日時のカラムを作り、論理削除のロジックを作っていく。

base_model.py
from django.db import models
from django.utils import timezone


class BaseQuerySet(models.query.QuerySet):
    def delete(self):
        return super(BaseQuerySet, self).update(deleted_at=timezone.now())

    def hard_delete(self):
        return super(BaseQuerySet, self).delete()

    def alive(self):
        return self.filter(deleted_at=None)

    def dead(self):
        return self.exclude(deleted_at=None)


class BaseManager(models.Manager):
    def __init__(self, *args, **kwargs):
        self.alive_only = kwargs.pop('alive_only', True)
        super(BaseManager, self).__init__(*args, **kwargs)

    def get_queryset(self):
        if self.alive_only:
            return BaseQuerySet(self.model).filter(deleted_at=None)
        return BaseQuerySet(self.model)

    def hard_delete(self):
        return self.get_queryset().hard_delete()


class BaseModel(models.Model):
    # auto_now_add はインスタンスの作成(DBにINSERT)する度に更新
    created_at = models.DateTimeField('作成日時', auto_now_add=True)
    # # auto_now=Trueの場合はモデルインスタンスを保存する度に現在の時間で更新
    updated_at = models.DateTimeField('更新日時', auto_now=True)
    deleted_at = models.DateTimeField('削除日時', blank=True, null=True)

    objects = BaseManager()
    all_objects = BaseManager(alive_only=False)

モデル

各モデルでベースモデルを継承する。
created_at updated_at deleted_atはベースモデルで設定し、継承しているので、モデルでは設定する必要はない。

news_model.py
from django.db import models
from .base_model import BaseModel, BaseManager

class NewsManager(BaseManager):
    ...


class News(BaseModel):
    ...

    objects = NewsManager()
    all_objects = NewsManager(alive_only=False)

論理削除

News.objects.filter(...).delete()

削除

News.objects.filter(...).hard_delete()

論理削除したものも含めて検索

News.all_objects.filter(...)

削除していないデータ

News.all_objects.filter(...).alive()

論理削除したデータ

News.all_objects.filter(...).dead()

28
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?