on_delete 옵션 완벽 정복

Django 모델에서 ForeignKey나 OneToOneField 관계에서 참조되는 객체가 삭제될 때 참조하는 객체를 어떻게 처리할지 정의하는 on_delete 옵션에 대한 핵심 내용. CASCADE, PROTECT, SET_NULL, DO_NOTHING 네 가지 주요 옵션의 동작 방식과 실무 활용법

CASCADE: 함께 삭제

동작: 참조되는 객체가 삭제될 때 참조하는 모든 객체도 함께 삭제

사용 예시:

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

적용 상황:

  • 게시글과 댓글 관계 (게시글 삭제 시 댓글도 삭제)

  • 주문과 주문 항목 관계 (주문 취소 시 주문 항목도 삭제)

주의사항: User 모델 참조 시 특히 주의 필요 - 실수로 유저 삭제 시 관련된 모든 데이터가 연쇄 삭제될 수 있음

PROTECT: 삭제 방지

동작: 참조하는 객체가 하나라도 있으면 참조되는 객체의 삭제를 차단하고 ProtectedError 발생

사용 예시:

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.PROTECT)
    title = models.CharField(max_length=100)

적용 상황:

  • 회사와 직원 관계 (직원이 있으면 회사 삭제 불가)

  • 결제 완료된 주문 보호

특징: 관리자 페이지에서도 동일하게 삭제 차단

SET_NULL: 연결만 끊기

동작: 참조되는 객체 삭제 시 참조하는 객체의 외래 키 필드를 NULL로 설정

사용 예시:

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)
    title = models.CharField(max_length=100)

필수 조건: 반드시 null=True 옵션 함께 설정

적용 상황:

  • 게시글과 카테고리 관계 (카테고리 삭제 시 게시글은 미분류로 유지)

  • 작성자 탈퇴 시 게시물은 보존

주의사항:

  • 코드에서 해당 필드 접근 시 None 체크 필요

  • blank=Truerequired=False 추가 설정 고려

DO_NOTHING: 아무 작업 안 함

동작: Django ORM 레벨에서 아무런 작업을 수행하지 않음. 데이터베이스 제약 조건에만 의존

사용 예시:

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.DO_NOTHING)
    title = models.CharField(max_length=100)

적용 상황:

  • 데이터베이스 레벨에서 직접 제약 조건을 관리하고 싶을 때

  • 커스텀 삭제 로직을 별도로 구현할 때

  • 레거시 시스템과의 호환성이 필요한 경우

주의사항:

  • 참조 무결성 위반 시 데이터베이스 에러 발생 가능

  • 개발자가 수동으로 데이터 정합성 관리 필요

  • 일반적으로 권장되지 않는 옵션

Last updated