본문 바로가기
python/Django

Django 시그널

by Redking

매커니즘

  • 장고에서 시그널은 앱 간 통신 및 특정 이벤트에 대한 통지를 가능하게 하는 중요한 매커니즘입니다.

구조

Sender (송신자)

  • Sender는 시그널을 발생시키는 주체로, 어떤 동작이나 이벤트가 일어났을 때 이를 알리는 역할을 합니다.
  • 일반적으로 이는 특정 앱 또는 모듈에서 발생하는데, 예를 들면 유저가 생성되었을 때(user creation) 또는 모델의 저장(save) 등이 될 수 있습니다.

Signal (신호)

  • Signal은 발생한 이벤트를 표현하는 객체입니다. 이 객체에는 이벤트에 대한 정보와 추가 데이터가 담겨져 있습니다.
  • Sender에서 발생한 특정 동작을 나타내며, Receiver가 이를 이해하고 적절히 처리할 수 있도록 정보를 제공합니다.

Receiver (수신자)

  • Receiver는 시그널을 수신하고, 그에 따른 특정 동작이나 처리를 수행하는 부분입니다.
  • Receiver는 특정 이벤트에 대한 대응으로 미리 정의된 작업을 실행하게 되며, 이를 통해 시스템이나 앱 간의 상호작용이 가능해집니다.

이러한 구조를 통해 장고 어플리케이션은 각각 독립적으로 작동하면서도 필요한 정보를 주고받을 수 있습니다. 예를 들어, 유저가 생성되었다는 시그널이 발생하면, 이를 수신한 다른 앱이나 모듈에서는 그에 맞게 특정 작업을 수행할 수 있습니다. 이로써 시스템 전체가 유연하게 동작하고 상호작용할 수 있게 됩니다. 

 

실제 사용 예시

signals.py 파일 생성

  • 먼저, 해당 앱 내에 signals.py 파일을 생성합니다. 이 파일은 시그널과 관련된 동작을 정의하는 곳입니다.
# signals.py

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from your_app.models import UserProfile  # UserProfile 모델에 대한 import 필요

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    """유저가 생성되면 프로필을 자동으로 생성하는 함수"""
    if created:
        UserProfile.objects.create(user=instance)

 

Signal 함수 정의

  • signals.py 파일 내에서 유저 모델의 저장 시그널에 대한 함수를 정의합니다. 이 함수는 유저가 생성될 때마다 호출되도록 연결됩니다.
  • 이 함수는 post_save 시그널을 사용하여, User 모델에서 저장이 완료된 후에 호출되도록 설정합니다.
  • 함수 내부에서는 유저가 생성된 경우(created == True), UserProfile 모델에 대한 새로운 인스턴스를 생성합니다

시그널 연결

  • 이제 이 함수를 실제로 시그널과 연결해야 합니다. 이는 앱의 AppConfig 클래스의 ready 메서드를 이용합니다.
  • 앱의 AppConfig 클래스에 ready 메서드를 추가하고, 해당 메서드에서 signals 모듈을 import합니다. 이렇게 하면 앱이 로드될 때 시그널이 자동으로 등록됩니다. 
# apps.py

from django.apps import AppConfig

class YourAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'your_app'

    def ready(self):
        import your_app.signals  # signals 모듈을 여기서 import

 

UserProfile 모델 정의

  • 마지막으로, UserProfile 모델을 정의해야 합니다.
  • 이 모델은 User 모델과 일대일 관계로 연결되어 있습니다.
# models.py

from django.db import models
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
	...

 

이렇게 구현된 예시는 유저가 생성될 때마다 자동으로 프로필이 생성되도록 하는 기능입니다. 이를 통해 코드의 재사용성이 높아지고, 유지보수가 간편해집니다.

 

 

내장 시그널

Model Signals (모델 시그널):

Model signals는 데이터베이스 모델과 관련된 이벤트에 대한 시그널을 다룹니다.

  • pre_save는 모델의 저장이 일어나기 전에 발생합니다. 이 시점에서 모델의 필드들이 실제로 데이터베이스에 저장되기 전에 실행됩니다.
  • post_save는 모델의 저장이 완료된 후에 발생합니다. 모델이 성공적으로 저장된 후 추가 작업을 수행하고자 할 때 유용합니다.
  • pre_delete는 모델 인스턴스가 삭제되기 전에 발생합니다. 삭제 전에 추가적인 작업이 필요한 경우에 활용됩니다.
  • post_delete는 모델 인스턴스가 삭제된 후에 발생합니다. 모델이 삭제된 후 추가 작업을 수행하고자 할 때 사용됩니다.
  •  m2m_changed은 Many-to-Many 관계가 변경될 때 발생합니다. 예를 들어, Many-to-Many 필드에 새로운 항목이 추가되거나 제거될 때 이벤트를 처리할 수 있습니다.

Management Signals (매니지먼트 시그널):

Management signals는 마이그레이션과 관련된 이벤트에 대한 시그널을 다룹니다.

  • pre_migrate는 마이그레이션이 시작되기 전에 발생합니다. 마이그레이션 전에 추가 작업이 필요한 경우에 활용됩니다.
  • post_migrate는 마이그레이션이 완료된 후에 발생합니다. 마이그레이션 후에 추가 작업이 필요한 경우에 사용됩니다.

Request/Response Signals (요청/응답 시그널):

Request/Response signals는 HTTP 요청과 응답과 관련된 이벤트에 대한 시그널을 다룹니다.

  • request_started는 HTTP 요청 처리가 시작될 때 발생합니다. 이벤트에 대한 정보와 함께 요청이 시작되었음을 알리는 데 사용됩니다.
  • request_finished는 HTTP 요청 처리가 완료된 후에 발생합니다. 추가 작업이나 로깅과 같은 용도로 활용됩니다.
  • got_request_exception은 HTTP 요청 처리 중 예외가 발생할 때 발생합니다. 예외 처리나 로깅에 사용됩니다.

 

사용 주의 사항

동기적 실행

  • 시그널은 기본적으로 동기적으로 실행됩니다. 따라서 시그널 핸들러에서는 무거운 작업을 피해야 합니다.

에러 핸들링

  • 시그널 핸들러 내에서 발생한 에러는 무시되며, 전파되지 않습니다. 에러를 처리하려면 핸들러 내에서 적절한 예외 처리를 구현해야 합니다.

시그널의 과용

  • 시그널은 편리하지만 남발하면 코드를 이해하기 어려워질 수 있습니다. 필요한 경우에만 사용하고, 코드의 가독성을 유지하도록 노력해야 합니다.

트랜잭션과의 관련성

  • 일부 시그널은 트랜잭션과 관련이 있으므로 주의가 필요합니다. 특히, pre_save와 post_save는 데이터베이스 트랜잭션 내에서 실행되므로 트랜잭션 원자성에 영향을 줄 수 있습니다.

이렇게 다양한 내장 시그널을 통해 장고는 모델의 상태 변화, 데이터베이스 마이그레이션, HTTP 요청 및 응답과 관련된 이벤트를 감지하고 처리할 수 있습니다.

 

마무리

  • 시그널은 장고의 강력한 기능 중 하나로, 각 앱이 독립적으로 작동하면서도 상호 작용할 수 있도록 해줍니다.
  • 그러나 적절하지 않은 사용은 코드의 복잡성을 증가시킬 수 있으므로, 주의깊게 사용해야 합니다. 코드의 명확성과 가독성을 유지하며, 주석과 문서화를 통해 코드를 이해하기 쉽게 만들어야 합니다.
 
 
 

'python > Django' 카테고리의 다른 글

Django 5.0 버전 출시 전 살펴보기  (1) 2023.11.23
Django JSONField (Postgresql)  (0) 2022.12.06
Django bulk_create/bulk_update  (0) 2022.11.16
Django sitemap 분할 관리하기  (0) 2022.10.13
Django annotate management  (0) 2022.10.12

댓글