다음은 만족스러운 해결책은 아니지만 다음은 내가 해결한 해결책입니다.
나는 내 모든 모델에 추상 기본 클래스를 추가했습니다 :
class MyModel(models.Model):
class Meta:
abstract = True
def pre_delete_handler(self):
pass
신호 처리기가이 모델의 서브 클래스가 어떤 pre_delete
이벤트를 잡는다 : 내 각 모델에서
def pre_delete_handler(sender, instance, **kwargs):
if isinstance(instance, MyModel):
instance.pre_delete_handler()
models.signals.pre_delete.connect(pre_delete_handler)
, 자식 레코드가있는 경우 pre_delete_handler
메서드에서 예외를 throw하여 모든 "ON DELETE RESTRICT
"관계를 시뮬레이션합니다.
class RelatedRecordsExist(Exception): pass
class SomeModel(MyModel):
...
def pre_delete_handler(self):
if children.count():
raise RelatedRecordsExist("SomeModel has child records!")
데이터가 수정되기 전에 삭제가 중단됩니다.
불행히도 신호를 보내기 전에 삭제할 개체 목록이 Django에 의해 이미 생성되었으므로 pre_delete 신호 (예 : ON DELETE SET NULL
을 에뮬레이트)의 데이터를 업데이트 할 수 없습니다. Django는 순환 참조에 걸리는 것을 피하고 불필요하게 여러 번 객체에 신호를 보내지 않도록이 작업을 수행합니다.
이제 삭제를 수행 할 수 있는지 확인하는 것은 호출 코드의 책임입니다. delete()
메소드를 오버라이드 (override)하는, 내 views.py
및 models.py
에 너무 많은 코드를 변경하는 것을 방지하기 위해
class MyModel(models.Model):
...
def prepare_delete(self):
pass
이 돕기 위해 각 모델은 self.related_set.clear()
또는 유사한을 통해 NULL
에 키를 설정 돌봐 prepare_delete()
방법이있다
class MyModel(models.Model):
...
def delete(self):
self.prepare_delete()
super(MyModel, self).delete()
이 예상대로 명시 적으로 obj.delete()
를 통해 호출 어떤 삭제가 작동한다는 것을 의미하지만, 삭제가 직렬로 연결된 한 경우 관련 : MyModel
에 prepare_delete()
를 호출 d 개체를 사용하거나 queryset.delete()
을 통해 이루어지며 호출 코드가 필요한 경우 모든 링크가 끊어지는 것을 보장하지 않으면 pre_delete_handler
이 예외를 throw합니다.
그리고 마지막으로, 나는 post_delete
신호에 전화를 모델이 다른 데이터를 취소 할 수 있습니다 도착 모델과 유사한 post_delete_handler
방법을 추가했습니다 (ImageField
들에 대한 예를 삭제 파일을.)
class MyModel(models.Model):
...
def post_delete_handler(self):
pass
def post_delete_handler(sender, instance, **kwargs):
if isinstance(instance, MyModel):
instance.post_delete_handler()
models.signals.post_delete.connect(post_delete_handler)
나는 누군가를 돕고 코드가 너무 많은 문제없이 더 쓸모있는 것으로 다시 스레딩 될 수 있기를 바란다.
개선 방법에 대한 제안은 환영합니다.
일 - 워드 프로세서에 따라 설정이 '외래 키 필드에 대한 on_delete'도 장고 2.0에서 필요합니다. – whusterj