삭제된 데이터만 따로 모으는 섹션이 있으면 좋을 것 같아요.
말이 삭제지만 실제로는 섹션 이동만 하는거죠.
그리고 그 섹션에서는 영구삭제 or 원 위치로 복구 두가지 옵션만 있도록 하고요.
class SoftDeleteManager(models.Manager):
use_for_related_fields = True # 옵션은 기본 매니저로 이 매니저를 정의한 모델이 있을 때 이 모델을 가리키는 모든 관계 참조에서 모델 매니저를 사용할 수 있도록 한다.
def get_queryset(self):
return super().get_queryset().filter(deleted_at__isnull=True)
class TimeStampedModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
deleted_at = models.DateTimeField(null=True, default=None)
class Meta:
abstract = True # 상속 할수 있게
ordering = ["created_at"]
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'])
safedelete
를 추가해준다.from safedelete import DELETED_VISIBLE_BY_PK
from safedelete.managers import SafeDeleteManager
from safedelete.models import SafeDeleteModel, SOFT_DELETE_CASCADE
class CustomSafeDeleteManager(SafeDeleteManager):
_safedelete_visibility = DELETED_VISIBLE_BY_PK
class TimeStampedModel(SafeDeleteModel):
_safedelete_policy = SOFT_DELETE_CASCADE
created_at = models.DateTimeField(auto_now_add=True)
objects = CustomSafeDeleteManager()
class Meta:
abstract = True
ordering = ["created_at"]
_safedelete_policy
가 이 패키지의 정수인데 네가지 옵션 중 원하는 policy를 골라서 디폴트로 명시해주어도 되고 다른 policy가 임시로 필요한 경우 일회용으로 쓸 수도 있다. 이건 views에서 설명!apps.get_model('staffs', self.basename)
이라는 장고 빌트인 함수를 사용했다. 이 맛에 개발한다.from safedelete.models import HARD_DELETE
class SoftDeleteViewSet(viewsets.ViewSet):
@action(detail=False)
def deletes(self, request):
queryset_id_list = apps.get_model('staffs', self.basename).objects.deleted_only().values_list('id', flat=True)
return Response(queryset_id_list)
@action(detail=True, methods = ['patch', 'delete'])
def dodelete(self, request, pk):
queryset = apps.get_model('staffs', self.basename).objects.deleted_only().get(id=pk)
if self.request.method == "PATCH":
queryset.undelete()
queryset.save()
elif self.request.method == "DELETE":
queryset.delete(force_policy=HARD_DELETE)
queryset.save()
return Response(f'{self.request.method} successful')
deleted_only
attribute이 있는데 말 그대로 삭제처리가 된 객체를 모두 필터링해서 보여주고 참조할 수 있도록 해준다. 이를 활용해서 queryset을 오버라이딩했다. deleted_only
attribute을 통해서 현재 삭제처리가 된 데이터의 id리스트를 반환하고, 해당 id값을 통해 객체를 조회하면 정보가 보이게 된다.undelete()
과 delete(force_policy=none)
이라는 빌트인 함수가 있었기 때문에 이를 활용했고, 영구삭제 같은 경우는 HARD_DELETE policy를 활용하여 구현했다.