필자는 라라벨을 재미있게 다루다가 이직을 하면서 python 장고를 다루게 되었다. 라라벨에서 기본적으로 제공하는 많은 기능들은 장고에서 볼수가 없었기에 라라벨에서 기본으로 제공하는 좋은 기능들을 장고에서 솔선수범 구현하고 있어 글을 남기고자 한다.
class SoftDeleteModel(models.Model):
deleted_at = models.DateTimeField('삭제일', null=True, default=None)
class Meta:
abstract = True # 상속 할수 있게
objects = SoftDeleteManager() # 커스텀 매니저
def delete(self, using=None, keep_parents=False):
self.deleted_at = now()
self.save(update_fields=['deleted_at'])
def restore(self): # 삭제된 레코드를 복구한다.
self.deleted_at = None
self.save(update_fields=['deleted_at'])
class SoftDeleteManager(models.Manager):
use_for_related_fields = True # 옵션은 기본 매니저로 이 매니저를 정의한 모델이 있을 때 이 모델을 가리키는 모든 관계 참조에서 모델 매니저를 사용할 수 있도록 한다.
def get_queryset(self):
return super().get_queryset().filter(deleted_at__isnull=True)
class EstimateRequestBoard(CommonModel, SoftDeleteModel):
ANSWER_CHOICES = (
(0, '없음'),
(1, '완료'),
)
title = models.CharField(verbose_name='제목', max_length=100)
content = models.TextField('내용')
@pytest.mark.django_db
def test_softdelete():
# Given
mock_user = User.objects.create(username='Testuser')
title = "test"
content = "testcontent"
achievement = AchievementBoard()
achievement.title = title
achievement.content = content
achievement.owner = mock_user
achievement.save()
achievement2 = AchievementBoard()
achievement2.title = title
achievement2.content = content
achievement2.owner = mock_user
achievement2.save()
achievement3 = AchievementBoard()
achievement3.title = title
achievement3.content = content
achievement3.owner = mock_user
achievement3.save()
# When & Then
achievement.delete() # 삭제한다.
assert 2 == AchievementBoard.objects.count() # 삭제해서 총 2개
# When & Then
achievement.restore() # 복구한다.
assert 3 == AchievementBoard.objects.count() # 복구해서 총 3개
충분히 쉽게 장고에서도 소프트삭제를 구현할 수 있다. 위 기능은 아직 걸음마 단계이고 점차적으로 추가 할 생각이다.
우와.. 잘읽었습니다. 책 내시면 알려주세요! 혹시 hard delete의 경우 별도로 명시하는 것이 좋나요? 혹은 명시할 수 있는 방법이 있을까요?