Django signal 사용 요약

6055 단어 djangosignal
본문은 개인 블로그에 최초로 발표되었다Pylixm'wiki-django signal 사용 요약
최근에 이미 개발된 프로젝트에 기능을 추가하여django의signal을 생각해냈습니다. 정리기록은 다음과 같습니다.
django의 시그널이 뭐예요?
공식 설명서는 다음과 같습니다.
Django includes a “signal dispatcher” which helps allow decoupled applications get notified when actions occur elsewhere in the framework.In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. They’re especially useful when many pieces of code may be interested in the same events.
Django 내부에는 '신호 스케줄러' 가 포함되어 있습니다. 어떤 사건이 프레임워크에서 발생하면 프로그램에 알릴 수 있습니다.간단하게 말하면 이벤트 (이벤트) 가 발생할 때,signals (신호) 는 몇몇 senders (보내는 사람) 가receivers (수신자) 에게 알릴 수 있도록 허용한다.이것은 우리의 여러 개의 독립된 응용 코드가 같은 사건의 발생에 대해 모두 흥미를 느낄 때 특히 유용하다.
개인적으로django의signal은django 내부의 갈고리로 이해할 수 있으며 하나의 사건이 발생할 때 다른 프로그램은 그에 대해 관련 반응을 할 수 있으며 signal을 통해 정의된 처리 함수(receivers)를 리셋하여 우리 시스템을 더욱 크게 결합시킬 수 있다.
최적 사용 장면
알림 클래스
알림은 signal에서 가장 자주 사용하는 장면 중의 하나입니다.예를 들어 논단에서 게시물이 답장을 받을 때 건물주에게 통지한다.기술적으로 볼 때 우리는 알림 논리를 회신 저장에 놓을 수 있지만 이것은 좋은 처리 방식이 아니다. 이렇게 하면 프로그램의 결합도가 커지고 시스템의 후기 확장 유지보수에 불리하다.만약에 우리가 답장을 저장할 때 간단한 신호만 보내고 외부의 통지 논리가 신호를 받은 후에 다시 통지를 보낸다. 이렇게 하면 답장의 논리와 통지의 논리가 분리되고 후기 유지보수와 확장이 비교적 쉽다.
초기화 클래스
신호의 또 다른 열은 사건이 끝난 후에 일련의 초기화 작업을 하는 것이다.
기타 사용 장면 총결
다음의 경우 signal을 사용하지 마십시오.
  • signal은 하나의 모델과 밀접하게 관련되어 있으며 이 모델의save()로 이동할 수 있을 때
  • signal이 모델 관리자로 대체할 수 있을 때
  • signal은 하나의view와 밀접하게 관련되어 이view로 옮길 수 있을 때
  • 다음과 같은 경우 signal을 사용할 수 있습니다.
  • signal의receiver가 여러 모델을 동시에 수정해야 할 때
  • 여러 앱의 같은 signal을 같은receiver에서 처리할 때
  • 어떤 모델이 저장된 후에cache를 제거할 때
  • 다른 방법을 사용할 수 없지만 일부 문제를 처리하기 위해 피조정 함수가 필요할 때
  • 사용 방법
    django의 signal 사용은 두 개의 모듈로 나눌 수 있습니다.
  • signal:signal 정의 및 트리거 이벤트
  • receiver:signal 수용 함수
  • 내장 signal 사용
    django 내부에 정의된 signal이 있습니다.
    모델 관련:
  • pre_save 대상 save 전 트리거
  • post_save 대상save 후 터치
  • pre_delete 대상 delete 전 트리거
  • post_delete 대상 delete 후 트리거
  • m2m_changed ManyToManyField 필드가 업데이트되면 트리거
  • 관련 요청:
  • request_started 리퀘스트 요청 전 트리거
  • request_finished request 요청 후 트리거
  • django가 자체로 가지고 있는 signal에 대해 우리는receiver를 작성하기만 하면 됩니다. 아래와 같이 사용합니다.
    첫 번째,receiver를 작성하고signal에 귀속합니다myapp/signals/handlers.py
    from django.dispatch import receiver
    from django.core.signals import request_finished
     
    ## decorators     
    @receiver(request_finished, dispatch_uid="request_finished")
    def my_signal_handler(sender, **kwargs):
        print("Request finished!================================")
    
    #       
    def my_signal_handler(sender, **kwargs):
        print("Request finished!================================")
    
    request_finished.connect(my_signal_handler)
    
    #####################################################
    #   model  signal 
    from django.dispatch import receiver
    from django.db.models.signals import post_save
     
    from polls.models import MyModel
     
     
    @receiver(post_save, sender=MyModel, dispatch_uid="mymodel_post_save")
    def my_model_handler(sender, **kwargs):
     print('Saved: {}'.format(kwargs['instance'].__dict__))
    
  • dispatch_uid 이receiver를 한 번만 호출할 수 있도록 하기
  • 2단계, signal 로드myapp/__init__py
    default_app_config = 'myapp.apps.MySendingAppConfig'
    myapp/apps.py
    from django.apps import AppConfig
     
     
    class MyAppConfig(AppConfig):
        name = 'myapp'
     
        def ready(self):
            # signals are imported, so that they are defined and can be used
            import myapp.signals.handlers

    여기에서 시스템이 Request 요청을 받으면receiver를 실행합니다.
    기타 내장된 signal, 공식 문서 참조: https://docs.djangoproject.com/en/1.9/topics/signals/
    사용자 정의 signal 사용
    사용자 정의 signal, signal과receiver를 작성해야 합니다.
    첫 번째 단계, signal 작성myapp.signals.signals.py
    import django.dispatch
     
    my_signal = django.dispatch.Signal(providing_args=["my_signal_arg1", "my_signal_arg_2"])

    2단계, signal 로드myapp/__init__py
        
    default_app_config = 'myapp.apps.MySendingAppConfig'
    myapp/apps.py
    from django.apps import AppConfig
     
     
    class MyAppConfig(AppConfig):
        name = 'myapp'
     
        def ready(self):
            # signals are imported, so that they are defined and can be used
            import myapp.signals.handlers

    세 번째 단계, 이벤트가 터치될 때 signal 발송myapp/views.py
    from .signals.signals import my_signal
     
    my_signal.send(sender="some function or class",
                   my_signal_arg1="something", my_signal_arg_2="something else"])

    사용자 정의signal,django에서 이벤트 감청을 작성했습니다.
    4단계,signal 받아서receiver 실행myapp/signals/handlers.py
    from django.dispatch import receiver
    from myapp.signals.signals import my_signal
     
     
    @receiver(my_signal, dispatch_uid="my_signal_receiver")
    def my_signal_handler(sender, **kwargs):
        print('my_signal received')
    

    이 때, 우리가 사용자 정의한 signal이 개발되었다.
    총결산
  • django signal의 처리는 동기화되어 대량의 작업을 처리하는 데 사용되지 않습니다.
  • django signal은 프로그램의 결합, 코드의 복용과 유지보수성에 큰 도움이 된다.

  • 이상은 개인적인 관점으로 궁금한 점이 있으면 교류를 환영합니다.
    참고 자료
    http://sabinemaennel.ch/django/signals-in-django/ https://docs.djangoproject.com/en/1.10/topics/signals/ http://www.weiguda.com/blog/38/ http://www.python88.com/topic/151

    좋은 웹페이지 즐겨찾기