다음 설정을 사용하여 장고에서 소프트 삭제를 구현합니다. 내가 후드 아래 장고에 익숙하지 않아서 만날지도 모르는 것에 대한 의견을 보내 주시면 감사하겠습니다. 나는 특히 QuerySet을 서브 클래스 화하는 것을 불편하게 느낀다.동일한 테이블 Django ORM 소프트 삭제 방법 알았습니까?
기본적인 아이디어는 MyModel
에 delete
에 대한 첫 번째 호출은 현재 날짜에 MyModel
의 date_deleted
을 변경한다는 것입니다. 두 번째 delete
은 실제로 개체를 삭제합니다. 삭제 된 개체를 숨길 기본 관리부터 (A delete
를 잡는 것은 두 오버라이드 (override), 객체의 delete
방법을 우회 할 수있는 QuerySet
에있는 개체에 대한 하나 하나를. 필요), 삭제 된 개체가 사라 명시 적으로 deleted_objects
관리자를 통해 요청해야합니다.
이 설정을 사용하면 DeletionQuerySet
및 DeletionManager
을 정의하고 모델 (들)에 date_deleted
, objects
및 deleted_objects
를 추가해야합니다.
감사합니다,
추신, 필터링이 방법은 관리자가 strongly discouraged입니다 기본에서 개체를 언급하는 것을 잊었다!
class DeletionQuerySet(models.query.QuerySet):
def delete(self):
prev_deleted = self.filter(date_deleted__isnull=False)
prev_deleted.actual_delete()
prev_undeleted = self.filter(date_deleted__isnull=True)
prev_undeleted.update(date_deleted=datetime.datetime.now())
def actual_delete(self):
super(DeletionQuerySet, self).delete()
class DeletionManager(models.manager.Manager):
# setting use_for_related_fields to True for a default manager ensures
# that this manager will be used for chained lookups, a la double underscore,
# and therefore that deleted Entities won't popup unexpectedly.
use_for_related_fields = True
def __init__(self, hide_deleted=False, hide_undeleted=False):
super(DeletionManager, self).__init__()
self.hide_deleted = hide_deleted
self.hide_undeleted = hide_undeleted
def get_query_set(self):
qs = DeletionQuerySet(self.model)
if self.hide_deleted:
qs = qs.filter(date_deleted__isnull=True)
if self.hide_undeleted:
qs = qs.filter(date_deleted__isnull=False)
return qs
class MyModel(models.Model):
# Your fields here...
date_deleted = models.DateTimeField(null=True)
#the first manager defined in a Model will be the Model's default manager
objects = DeletionManager(hide_deleted=True)
deleted_objects = DeletionManager(hide_undeleted=True)
def delete(self):
if self.date_deleted is None:
self.date_deleted = datetime.datetime.now()
self.save()
else:
super(Agreement, self).delete()
한 가지 문제는 계단식 삭제입니다. 이 설정은 외래 키에 삭제를 알리는 일을하지 않습니다. 관련 엔티티가 (분명히 유효한) 외래 키를 따라 'MyModel'을 따라 가려고하면 아무 것도 얻을 수 없습니다. 프로그래머가 계단식 소프트 삭제를 구현한다고해도 모델의 기본 관리자가 서로 삭제 된 레코드를 숨길 때 소프트 삭제 된 모델이 서로를 어떻게 참조합니까? –
내 대답보기. 그것은 우리를 위해 잘 작동했습니다. 삭제 된 모델을 제외시키고 자하는 쿼리에서 객체 대신 object_soft를 사용하십시오. 이 방법은 외래 키 조회가 여전히 발생할 수 있습니다. https://stackoverflow.com/questions/42123972/django-orm-soft-delete-objects-with-flag-but-still-beable-to-look-them-up-in/47986069#47986069 –