Django 모델에서 on_delete의 역할
가능한 값:
- CASCADE: 참조하는 모델이 삭제되면 종속 모델도 함께 삭제됩니다.
- PROTECT: 참조하는 모델이 삭제되면 종속 모델은 삭제되지 않고, 참조하는 모델 ID는 null 값으로 설정됩니다.
- SET_NULL: 참조하는 모델이 삭제되면 종속 모델의 참조하는 필드 값은 null 값으로 설정됩니다.
- DO_NOTHING: 참조하는 모델이 삭제되더라도 종속 모델에는 아무런 영향이 없습니다.
예시:
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
위 예시에서 Author
모델은 Book
모델을 참조하는 외래키를 가지고 있으며, on_delete
옵션은 CASCADE
로 설정되어 있습니다. 만약 Book
모델의 인스턴스가 삭제되면, 해당 책을 저술한 Author
모델의 인스턴스도 함께 삭제됩니다.
선택 가이드:
- CASCADE: 참조하는 모델과 종속 모델 간에 강한 관계가 존재하는 경우 사용합니다. 예를 들어, 책과 저자의 관계처럼 책이 삭제되면 해당 책을 저술한 저자도 삭제해야 하는 경우 사용합니다.
- PROTECT: 참조하는 모델과 종속 모델 간에 약한 관계가 존재하는 경우 사용합니다. 예를 들어, 사용자와 프로필의 관계처럼 사용자가 삭제되더라도 프로필은 유지해야 하는 경우 사용합니다.
- SET_NULL: 참조하는 모델이 삭제되더라도 종속 모델을 유지해야 하지만, 참조하는 모델 ID를 추적할 필요가 없는 경우 사용합니다.
- DO_NOTHING: 참조하는 모델이 삭제되어도 종속 모델에 영향을 주고 싶지 않은 경우 사용합니다.
Django 모델에서 on_delete 옵션 예시
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
# Book 인스턴스 삭제 시 연관된 Author 인스턴스도 함께 삭제
book = Book.objects.get(pk=1)
book.delete()
# Author 인스턴스 확인
author = Author.objects.filter(book=book).first()
print(author) # None 출력
PROTECT 예시:
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.PROTECT)
# Book 인스턴스 삭제 시 연관된 Author 인스턴스는 삭제되지 않고 book_id 필드가 null 값으로 설정
book = Book.objects.get(pk=1)
book.delete()
# Author 인스턴스 확인
author = Author.objects.filter(book=book).first()
print(author.book_id) # None 출력
SET_NULL 예시:
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.SET_NULL)
# Book 인스턴스 삭제 시 연관된 Author 인스턴스의 book 필드를 null 값으로 설정
book = Book.objects.get(pk=1)
book.delete()
# Author 인스턴스 확인
author = Author.objects.filter(book=book).first()
print(author.book) # None 출력
SET_DEFAULT 예시:
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.SET_DEFAULT, default=1)
# Book 인스턴스 삭제 시 연관된 Author 인스턴스의 book 필드를 기본값으로 설정
book = Book.objects.get(pk=1)
book.delete()
# Author 인스턴스 확인
author = Author.objects.filter(book=book).first()
print(author.book_id) # 1 출력
DO_NOTHING 예시:
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.DO_NOTHING)
# Book 인스턴스 삭제 시 연관된 Author 인스턴스에 영향 없음
book = Book.objects.get(pk=1)
book.delete()
# Author 인스턴스 확인
author = Author.objects.filter(book=book).first()
print(author) # Book 인스턴스 삭제에도 불구하고 여전히 존재
Django 모델에서 on_delete 옵션의 대체 방법
signals 사용:
pre_delete
시그널을 사용하여 참조하는 모델이 삭제되기 전에 종속 모델을 처리할 수 있습니다.
from django.db.models.signals import pre_delete, post_delete
def pre_delete_book(sender, instance, **kwargs):
# Book 인스턴스 삭제 전에 연관된 Author 인스턴스 처리
author = Author.objects.filter(book=instance).first()
# ...
def post_delete_book(sender, instance, **kwargs):
# Book 인스턴스 삭제 후에 연관된 Author 인스턴스 처리
author = Author.objects.filter(book=instance).first()
# ...
pre_delete.connect(pre_delete_book, sender=Book)
post_delete.connect(post_delete_book, sender=Book)
직접적인 코드 구현:
CASCADE
옵션과 유사한 동작을 원할 경우, 직접 코드를 작성하여 종속 모델을 삭제할 수 있습니다.
def delete_book(book):
# Book 인스턴스 삭제
book.delete()
# 연관된 Author 인스턴스 삭제
Author.objects.filter(book=book).delete()
CASCADE 옵션과 null=True 옵션 함께 사용:
- 참조하는 모델이 삭제되어도 종속 모델을 유지해야 하지만, 참조하는 모델 ID를 추적할 필요가 없는 경우
CASCADE
옵션과null=True
옵션을 함께 사용할 수 있습니다.
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
book = models.ForeignKey(Book, on_delete=models.CASCADE, null=True)
주의 사항:
on_delete
옵션 대체 방법은 상황에 따라 유용하지만, 데이터 무결성을 유지하기 위해 신중하게 사용해야 합니다.signals
사용 시, 시그널 순서 및 처리 로직에 주의해야 합니다.- 직접적인 코드 구현 시, 코드 중복 및 오류 가능성을 고려해야 합니다.
django django-models