2009-10-08 3 views
15

some_widget_instance.delete()를 사용하여 위젯을 삭제하기 때문에 문제가 있습니다. WidgetFile이 삭제 될 때 하드 드라이브에서 파일을 삭제할 수 있도록 override delete() 메소드가있는 WidgetFile이라는 모델도 있습니다. 제가하는 데 문제는입니다 나는 위젯을 삭제하고이처럼 관련 WidgetFiles 경우 :모델에서 delete()를 오버라이드하고 관련 삭제 작업을 계속 수행하려면 어떻게합니까?

class WidgetFile(models.Model): 

    widget = models.ForeignKey(Widget) 

음, 위젯, 그것은 WidgetFiles가 삭제 있다는 삭제하지만 때 삭제() 메소드 아무튼를 방아쇠를 당기고 내 여분의 하드 드라이브 물건을하십시오. 어떤 도움이라도 대단히 감사합니다.

+0

이 문제는 위젯이 삭제 될 때 각 위양 (외부 키 참조가있는 클래스)에서 delete() 메소드를 트리거하지 않기 때문에 발생합니다. 단순히 관련 객체를 DB에서 삭제합니다. 이것은 더 효율적이긴하지만 분명히 이와 같은 문제를 야기합니다. – orokusaki

답변

24

내가 그것을 알아 냈 :

django-following-relationships-backward

예를 참조하십시오. 난 그냥 그 위젯 모델이 넣어 :

def delete(self): 
    files = WidgetFile.objects.filter(widget=self) 
    if files: 
     for file in files: 
      file.delete() 
    super(Widget, self).delete() 

따라서 코드를 삭제하는 내 사용자 지정 파일을 트리거, 관련 각 개체에 필요한 삭제() 메소드를 트리거. 더 많은 데이터베이스 비싼 네,하지만 어쨌든 하드 드라이브에 파일을 삭제하려고 할 때, DB를 몇 번 추가하는 것은 큰 비용이 아닙니다.

그것은 django 사이트에 설명과 같아야합니다
+0

Celery 또는 cron이 삭제되는 파일이 다른 프로세스에서 읽기/쓰기 작업을 위해 이미 열릴 수있는 유사한 상황이 발생하지 않는다고 생각하는 이유는 분명하지 않습니다. 두 경우 모두 특별한 경우를 처리하도록 코딩해야합니다. –

+2

나는 그 비트를 제거했다 ... 4.5 년 전에 나는 그것이 좋은 생각일지도 모른다라고 생각했다. 그러나 나는 확실히 이유가 아니다. – orokusaki

1

some_widget_instanceWidget 또는 WidgetFile의 인스턴스입니까? Widget의 인스턴스 인 경우 사용자 정의 delete() 함수를 가져 오지 않으므로 WidgetFile 클래스에 있습니다.

1

하나의 위젯이 하나의 WidgetFile에 정확하게 연결되어있는 경우에만 의미가있는 것처럼 보입니다. pre-deletesignal :이 경우 당신은이 문제를 해결 가능한 방법으로 던져 OneToOneField

# Delete the restaurant; the waiter should also be removed 
>>> r = Restaurant.objects.get(pk=1) 
>>> r.delete() 
+0

참으로 사실이지만 Django는 각 삭제 메소드를 트리거하지 않고 모든 웨이터에 대해 데이터베이스 수준의 대량 삭제를 수행합니다. 이는 비용이 적게 들지만 덜 일반적이기도합니다. – orokusaki

2

삭제하기 전에 clear()을 사용하면 관련된 객체 세트에서 모든 객체가 제거됩니다.

group.link_set.clear() 
group.delete() 
50

을 통과 잊고 장고에 덩어리를 발견 당신이 생각해야 할 문서들. 검색어 세트를 사용하여 대량의 개체를 삭제할 때 개체의 삭제() 메서드가 반드시 호출되지 삭제 참고 재정의

Overriding predefined model methods

. 사용자 정의 삭제 논리를 실행하려면 pre_delete 및/또는 post_delete 신호를 사용할 수 있습니다.

즉, 이 아닙니다. Signals을 사용하면 삭제를 처리 할 때 더 좋은 옵션입니다.

나는 다음과 같이했다 :

import shutil 
from django.db.models.signals import pre_delete 
from django.dispatch import receiver 

@receiver(pre_delete) 
def delete_repo(sender, instance, **kwargs): 
    if sender == Set: 
     shutil.rmtree(instance.repo) 
0

을 장고 1.9에서, 당신은 단지 필드 on_delete=models.CASCADE를 정의한다면, 그것은 삭제에 관련된 모든 개체를 제거합니다.

+0

이것은 옳지 않습니다. 문제는 계단식 삭제에 관한 것이 아닙니다. 그것은 관련된'delete' 메소드가 호출되도록하는 것입니다. – orokusaki

관련 문제