[엉박사] 1.6 signals.py

impala·2023년 1월 12일
0
post-thumbnail

1.6 signals.py

프로젝트를 진행하면서 DB에 데이터를 넣을 때 다른 테이블에서 그 개수를 유지하거나, 특정 테이블에 데이터를 넣으면 다른 테이블에 인스턴스를 생성해서 연결해야 할 경우가 있었다. 구체적인 경우는 다음과 같다.

  • chapter에 데이터를 추가하면 텍스트를 문장단위로 분할하여 저장
  • chapter가 추가되거나 삭제되면 book에서 chapter의 개수를 갱신
  • quiz가 추가되거나 삭제되면 chapter에서 quiz의 개수를 갱신
  • report가 생성되면 text를 생성하여 연결

serializers.py에서 이 작업을 수행하기에는 데이터의 입력이 클라이언트로부터 오지 않는 경우가 있었고, models.py에서 수행하기에는 객체가 생성되는 시점에서의 작업을 처리할 방법이 마땅치 않아 방법을 찾아보던 중 장고의 signal 을 찾게 되었다.

signal이란 다른 곳에서 특정 작업이 발생할 때 신호를 주어 신호가 올 때마다 사용자가 지정한 작업이 수행될 수 있도록 하는 기능이다.

장고의 signal을 사용하는 방법은 다음과 같다.

  1. 모델 정의
  2. signals.py작성
    • @receiver decorator로 신호를 수신. 인자는 신호의 종류와 신호를 보내는 sender class
    • 메소드 안에 신호를 수신하면 수행할 작업을 정의
    @receiver(post_save, sender=MyModel)
    def my_callback(sender, **kwargs):
    # 신호를 수신하면 수행할 작업
  3. apps.py에 signal.py를 등록
    class MyAppConfig(AppConfig):
        def ready(self):
            from . import signals
  4. init.py에 Configuration class 등록
    default_app_config = 'myapp.apps.MyAppConfig'

장고에서 제공하는 signal의 종류는 아래와 같다.

  • pre_init, post_init
  • pre_save, post_save
  • pre_delete, post_delete
  • m2m_changed
  • class_prepared
  • pre_migrate, post_migrate
  • request_started, request_finished
  • got_request_exception
  • setting_changed (from testcode)
  • template_rendered (from testcode)
  • connection_created (from DB)

signal을 사용하면 편리할 수 있지만 코드가 길어질 경우 코드를 이해하기 어렵게 만들 수 있다. 그러므로 장고 공식문서에서는 되도록이면 처리코드를 직접 호출하고 불가피한 경우에만 사용하는 것을 권장하고있다.

0개의 댓글