Django 신호(Signal) 설정 방법과 주요 신호 종류 총정리

Django 신호(Signal)는 특정 이벤트가 발생했을 때 추가적인 로직을 실행할 수 있게 해주는 강력한 메커니즘이다. 신호를 제대로 사용하기 위해서는 설정 방법과 각 신호의 용도를 정확히 이해해야 한다.

신호 처리기가 동작하지 않을 때의 해결 방법

신호 처리기를 구현했는데 아무런 출력이 없다면, 다음 사항들을 점검해야 한다.

1. apps.py 설정 확인

# myapp/apps.py
from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'myapp'
    verbose_name = '고객 관리 시스템'
    
    def ready(self):
        import myapp.signals  # 신호 모듈 임포트 필수

2. __init__.py 설정

# myapp/__init__.py
default_app_config = 'myapp.apps.MyAppConfig'

3. 신호 처리기 코드 작성

# myapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from myapp.models import Order

@receiver(post_save, sender=Order)
def order_post_save(sender, instance, created, **kwargs):
    print('주문 모델 신호 수신')
    print(f'인스턴스: {instance}')
    print(f'생성 여부: {created}')
    print(f'추가 파라미터: {kwargs}')

4. 모델 저장 로직 확인

# myapp/views.py
from myapp.models import Order

def create_order(request):
    order = Order(customer_name='홍길동', product='노트북', quantity=1)
    order.save()  # 실제 저장 실행 확인

5. settings.py 앱 등록

# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    # ...
    'myapp',  # 앱 이름 정확히 기입
]

6. 서버 재시작

설정 변경 후에는 반드시 Django 개발 서버를 재시작해야 한다.

7. 디버깅을 위한 로깅 추가

@receiver(post_save, sender=Order)
def order_post_save(sender, instance, created, **kwargs):
    import logging
    logger = logging.getLogger(__name__)
    
    logger.info(f'주문 생성: {instance.id}')
    logger.debug(f'생성 여부: {created}')
    
    # 파일로도 기록
    try:
        with open('signal_debug.log', 'a') as f:
            f.write(f'주문 신호 실행: {instance}\n')
    except Exception as e:
        print(f'로그 작성 오류: {e}')

8. 에러 로그 확인

서버 터미널과 Django 에러 로그를 확인하여 예외 사항이 있는지 점검한다.

9. 신호 모듈 로드 확인

# myapp/signals.py
print('신호 모듈 로드 완료')  # 시작 시 출력 확인

from django.db.models.signals import post_save
from django.dispatch import receiver
from myapp.models import Order

10. 저장 전후 상태 확인

def save_order():
    order = Order(customer_name='홍길동', product='노트북')
    print('저장 전:', order.id)
    order.save()
    print('저장 후:', order.id)

Django 신호의 종류

1. 모델 신호 (Model Signals)

  • pre_save: 모델 인스턴스 저장 직전에 발생
  • post_save: 모델 인스턴스 저장 직후에 발생
  • pre_delete: 모델 인스턴스 삭제 직전에 발생
  • post_delete: 모델 인스턴스 삭제 직후에 발생
  • m2m_changed: ManyToMany 관계 변경 시 발생
  • pre_init: 모델 인스턴스 초기화 전에 발생
  • post_init: 모델 인스턴스 초기화 후에 발생

2. 데이터베이스 신호 (Database Signals)

  • pre_migrate: 마이그레이션 실행 전에 발생
  • post_migrate: 마이그레이션 실행 후에 발생

3. 요청/응답 신호 (Request/Response Signals)

  • request_started: HTTP 요청 처리 시작 시 발생
  • request_finished: HTTP 요청 처리 완료 시 발생
  • got_request_exception: 요청 처리 중 예외 발생 시 발생

4. 관리 명령 신호 (Management Signals)

  • pre_migrate: migrate 명령어 실행 전
  • post_migrate: migrate 명령어 실행 후

5. 사용자 인증 신호 (User Authentication Signals)

  • user_logged_in: 사용자 로그인 성공 시
  • user_logged_out: 사용자 로그아웃 시
  • user_login_failed: 사용자 로그인 실패 시

6. 기타 신호

  • connection_created: 데이터베이스 연결 생성 후

신호 사용 예제

모델 신호 활용

from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from myapp.models import Product, Inventory

@receiver(post_save, sender=Product)
def product_saved(sender, instance, created, **kwargs):
    if created:
        Inventory.objects.create(product=instance, stock=0)
        print(f'새 제품 재고 생성: {instance.name}')
    else:
        print(f'제품 정보 업데이트: {instance.name}')

@receiver(pre_delete, sender=Product)
def product_deleting(sender, instance, **kwargs):
    print(f'제품 삭제 진행: {instance.name}')

요청 신호 활용

from django.core.signals import request_started, request_finished
from django.dispatch import receiver

@receiver(request_started)
def request_started_handler(sender, **kwargs):
    print('새 요청 시작')

@receiver(request_finished)
def request_finished_handler(sender, **kwargs):
    print('요청 처리 완료')

사용자 인증 신호 활용

from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.dispatch import receiver

@receiver(user_logged_in)
def login_success(sender, request, user, **kwargs):
    print(f'로그인 성공: {user.username}')

@receiver(user_logged_out)
def logout_success(sender, request, user, **kwargs):
    print(f'로그아웃: {user.username}')

Django 신호를 잘 활용하면 모델 상태 변경 추적, 로그 기록, 캐시 무효화, 데이터 동기화 등 다양한 기능을 구현할 수 있다. 신호 설정 시에는 apps.py의 ready() 메서드에서 신호 모듈을 반드시 임포트해야 하며, 서버 재시작을忘رات 않아야 한다.

태그: Django signals python web-development django-signals

6월 27일 18:50에 게시됨