2009-04-13 3 views
12

Django 응용 프로그램에서 레코드를 삭제하는 대신 "삭제됨"으로 표시하고 활성 쿼리에서 숨길 수 있습니다. 내 주된 이유는 우연히 레코드를 삭제할 경우 (이 레코드는 특정 백엔드 감사 추적에 필요할 수도 있습니다) 사용자에게 삭제 취소 옵션을 제공하는 것입니다.실제로 어떻게 장고 모델에서 삭제 된 레코드를 실제로 삭제하는 대신 표시 할 수 있습니까?

많은 외래 키 관계가 있으므로 나는 삭제 된 레코드를이 레코드에 "캐스 캐 이드 (Cascade)"플래그로 표시해야합니다. 어떤 도구, 기존 프로젝트 또는 방법을 사용해야합니까?

답변

11

장고는 정확한 메커니즘을 제공합니다.

관련 개체를 통해 액세스하는 데 사용되는 관리자를 변경할 수 있습니다. 새 사용자 정의 관리자가 부울 필드에서 객체를 필터링하면 비활성화 된 객체는 요청에 표시되지 않습니다. http://docs.djangoproject.com/en/dev/topics/db/managers/#using-managers-for-related-object-access

+1

하지만 다른 개체의 검색이 이것을 존중한다고 생각하지 않습니다. 즉, 관련 모델에서 검색하는 경우 삭제 된 레코드를 무시하는 관리자를 사용합니다. 즉, 삭제 된 것으로 표시된 레코드는 여전히 관계가 유지됩니다. 이는 아마도 원하는 것은 아닙니다. – fastmultiplication

+0

@fastmultiplication "삭제 된 레코드를 무시하는 관리자를 사용합니다"라는 말은 삭제 된 플래그를 무시한다는 의미입니까, 즉 삭제 레코드가 포함됩니까? 그것이 내가 보는 행동입니다. –

+2

오른쪽. 관리자를 사용하여 액세스 할 수있는 객체를 제어하는 ​​것은 해당 클래스를 사용할 때만 작동합니다. 클래스 A가 매니저를 사용하여 "삭제 된"오브젝트를 숨기고 있다고 가정하면, A.objects는 삭제 된 오브젝트를 숨길 것입니다. 그러나 A가 B 클래스와 관련이 있다면, B.filter (a__name = 'smith')'는 삭제 된 A 객체를 모두 검색합니다. – fastmultiplication

4

좋은 질문입니다. 어떻게 효율적으로이 작업을 수행 할 수 있는지 궁금합니다.

이 트릭을 수행 할지는 확실치 않지만 django-reversion은 원하는대로 할 수 있습니다.하지만 비효율적 인 방법으로이 목표를 달성하는 방법을 검토하고 싶을 수도 있습니다. 이 다른 모델에서 검색을 위해 작동하지 않을 것입니다하지만

또 다른 생각은, 당신의 모델에 후 자동으로 필터를 추가하는 사용자 지정 관리자를 만드는 지칠대로 지친 부울 플래그를 가지고하는 것입니다. 또 다른 솔루션 suggested here은 과도한 것처럼 보이는 모든 항목의 중복 모델을 가지고 있지만 실제로 작동 할 수도 있습니다. 거기의 의견은 또한 다른 옵션을 논의합니다.

나는 대부분이 부분에서 나는 번거 로움의 가치가있는 이러한 솔루션을 고려하지 않는다고 덧붙일 것이다. 나는 보통 그것을 빨아 부울 플래그에 대한 내 검색을 필터링합니다. 너무 영리 해 지려고하면 많은 문제를 피할 수 있습니다. 물론 통증이 있으며 건조하지는 않습니다. 합리적인 솔루션은 사용자 정의 관리자가 해당 모델을 통해 관련 모델을 검색하려고 시도 할 때 제한 사항을 인식하는 동안 사용자 정의 관리자가 혼합 된 것입니다.

+0

+1 - 저는이 프로젝트에 대해 들어 본 적이 없었습니다 ... 롤백 기능만으로는 사실 만만합니다! –

+0

django-reversion은 멋지지만,이 경우 절대 과용됩니다. 그렇죠? 우리는 객체의 저장된 여러 버전 중 하나로 롤백하지 않고 불리언 상태를 뒤집는 것에 대해 이야기하고 있습니다. – ozan

+0

@ozan : "대부분의 경우이 솔루션을 고려하지 않아도됩니다." –

3

나는 'is_active'플래그를 사용하는 것이 좋다고 생각합니다. db 레벨에서 관련 항목에 플래그를 캐스케이드 할 필요는 없으며, 단지 부모의 상태를 계속 참고해야합니다. 이것은 contrib.auth의 사용자 모델에서 일어난 일입니다. 기억하지 마라. is_active가 아닌 사용자로 표시하면 django가 관련 모델을 탐색하고 마술처럼 레코드를 비활성화하려고하지 않고, 해당 모델의 해당 is_active 특성을 계속 확인합니다. 관련 항목.

예를 들어 각 사용자가 많은 북마크를 갖고 있고 비활성 사용자의 북마크를 표시하지 않으려면 bookmark.user.is_active가 true인지 확인하십시오. 책갈피 자체에 is_active 플래그가 필요하지는 않습니다.

3

여기 전에 몇 년에서 그렉 알라에서 빠른 블로그 자습서,하지만 장고 1.3을 사용하여 구현하고 좋았어요 :

더 자세한 내용은 여기를 참조하십시오. soft_delete, undelete 및 hard_delete라는 객체에 메서드를 추가했습니다.이 메서드는 self.deleted = True, self.deleted = False 및 self.delete()를 각각 반환했습니다.내가 뭔가를 기본 관리자 및 검색어 세트는 논리적 삭제에 가져다 방법을 삭제 대체 한 https://github.com/meteozond/django-permanent/ 을 개발하고 있어요 https://www.djangopackages.com/grids/g/deletion/

:

A Django Model Manager for Soft Deleting Records and How to Customize the Django Admin

0

이 기능을 제공하는 여러 패키지가 있습니다. 한 가지 예외를 제외하고는 기본 Django 삭제 메서드를 완전히 숨 깁니다. 관계가 삭제 된 경우에도 삭제 대신 PermanentModel에서 상속 된 모델을 표시합니다.

관련 문제