Django에서 model.save() 신호, 써보셨나요? 처음엔 저도 꽤 헷갈렸는데, 이제는 꽤 익숙해져서 여러분께 팁을 좀 드릴 수 있을 것 같아요. 사실 Django 개발하다 보면 model.save()는 정말 자주 쓰는 기능인데, 이게 단순히 데이터 저장만 하는 게 아니더라고요. pre_save랑 post_save라는 신호(signal)라는 게 붙어서, 데이터 저장 전후로 다양한 작업을 할 수 있게 해줘요. 근데 이 신호들이 어떤 순서로 실행되는지 몰라서 애먹은 적이 한두 번이 아니었죠. 그래서 오늘은 제가 직접 겪은 경험과 팁을 바탕으로, 이 신호들의 순서와 활용법을 쉽게 설명해 드리려고 합니다.
자, 핵심은 pre_save와 post_save 두 가지 신호예요. 이름만 봐도 대충 감이 오시죠? pre_save는 데이터베이스에 저장 하기 전에, post_save는 저장 한 후에 실행되는 신호입니다. sender라는 인자가 붙어서 어떤 모델의 신호인지 알려주고요. 생각보다 간단하죠?
pre_save는 데이터 검증이나 값 수정 같은 걸 하기에 딱 좋아요. 예를 들어, 제가 글쓰기 웹사이트를 만들었는데, 사용자가 제목을 안 쓰고 글을 저장하려고 하면, pre_save에서 제목을 "무제"로 자동 설정해 줄 수 있죠. 그리고 commit=False 옵션을 쓰면, save() 메서드 안에서도 pre_save 신호를 쓸 수 있어요. 이 부분은 좀 복잡해 보일 수 있지만, 나중에 좀 더 복잡한 작업을 할 때 유용하게 쓰일 거예요.
post_save는 데이터 저장 후에 실행되니까, 저장 후 처리나 관련 데이터 생성에 사용하면 좋습니다. 예를 들어, 새로운 게시글이 저장되면 이메일 알림을 보내거나, 관련 통계를 업데이트하는 작업을 여기서 처리할 수 있어요. 그리고 created=True라는 인자를 통해 새로운 레코드인지 아닌지 확인할 수도 있고요. 이게 꽤 유용한데, 새로운 레코드일 때만 특정 작업을 하도록 설정할 수 있거든요.
자, 그럼 실제 코드를 한번 볼까요? 제가 Article 모델을 만들어서 pre_save와 post_save 신호를 어떻게 쓰는지 보여드릴게요. 아래 코드는 제가 실제로 프로젝트에서 사용했던 코드를 약간 수정한 거예요.
from django.db import models
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
@receiver(pre_save, sender=Article)
def pre_save_article(sender, instance, **kwargs):
print("pre_save signal triggered")
if not instance.title:
instance.title = "Untitled Article"
@receiver(post_save, sender=Article)
def post_save_article(sender, instance, created, **kwargs):
print("post_save signal triggered")
print(f"Created: {created}")
if created:
# 새로운 Article 생성 시 추가 작업 수행
print("New article created!")
# 테스트 코드 (실행 전 migrations 및 데이터베이스 설정 필요)
article = Article(content="Sample content")
article.save()
이 코드를 실행하면 콘솔에 pre_save 신호가 먼저, 그 다음에 post_save 신호가 출력되는 걸 볼 수 있을 거예요. 정말 간단하죠? 하지만, 여기서 중요한 점이 하나 있어요. 절대 pre_save 신호 안에서 instance.save()를 호출하면 안 됩니다! 무한 루프에 빠질 수 있거든요. 이 부분은 꼭 기억해 두세요!
그리고 또 하나, pre_save와 post_save에서 데이터를 수정할 때는 데이터 일관성을 유지하는 게 정말 중요해요. 한쪽에서 수정한 데이터가 다른 쪽에서 또 수정되면 예상치 못한 문제가 발생할 수 있습니다. 저도 처음에 이 부분 때문에 꽤 고생했었죠.
마지막으로, 신호 처리 로직은 간결하고 효율적으로 작성하는 게 좋아요. 너무 복잡한 연산을 넣으면 성능이 저하될 수 있으니까요. 그리고, 항상 테스트를 철저히 해야 합니다! 다양한 상황을 고려해서 테스트를 해야 예상치 못한 오류를 미리 잡을 수 있죠.
결론적으로, Django의 model.save() 신호는 정말 강력한 기능이지만, 주의해야 할 점들이 몇 가지 있습니다. 신호들의 순서를 잘 이해하고, 데이터 일관성과 성능을 고려해서 사용해야 합니다. 이 글이 여러분의 Django 개발에 조금이나마 도움이 되었기를 바랍니다! 궁금한 점이 있으면 언제든지 질문해주세요!
댓글
댓글 쓰기