신호 메커니즘 Signal

4278 단어
Django는 프레임워크의 다른 곳에서 작업이 발생할 때 알림을 받을 수 있도록 '신호 배달기' 를 제공합니다.간단하게 말하자면, 신호는 몇몇 sender (보낸 사람) 에게 한 그룹 receiver (수신자) 의 일부 조작이 이미 발생했음을 알릴 수 있도록 허용한다.이것은 여러 개의 코드가 같은 사건과 관련이 있는 상황에서 매우 유용하다.Django는 사용자의 코드가 Django의 특정 작업에 대한 알림을 받을 수 있도록 내장 신호를 제공합니다.여기에는 다음과 같은 유용한 알림이 포함됩니다.
  • django.db.models.signals.pre_save django.db.models.signals.post_save는 모델 save () 방법이 호출되기 전이나 이후에 발송됩니다.
  • django.db.models.signals.pre_delete django.db.models.signals.post_delete는 모델 delete () 방법이나 조회 집합의 delete () 방법이 호출되기 전이나 이후에 발송됩니다.
  • django.db.models.signals.m2m_changed 모델에서 ManyToManyField가 수정될 때 보냅니다.
  • django.core.signals.request_started django.core.signals.request_finished Django에서 HTTP 요청을 설정하거나 닫을 때 보냅니다.

  • 사용자 지정 신호
    class Signal([providing_args=list])​
    

    모든 신호는django입니다.dispatch.Signal의 인스턴스입니다.providing_args는 매개 변수 이름 목록입니다. 실제로 이 매개 변수들은 그다지 쓸모가 없습니다.예를 들면 다음과 같습니다.
    from django.dispatch import Signal
    
    pizza_done = Signal(providing_args=["toppings", "size"])
    

    이 코드는 피자 를 성명했다done 신호, 수용자에게 toppings와size 파라미터를 제공합니다.
    Receiver 함수
    receiver는 리셋 함수에 해당하며, 관련 이벤트가 발생하면 실행을 촉발합니다.
    def my_callback(sender, **kwargs):
        print "Request finished!"
    

    주의: 함수는sender 매개 변수와 어댑터 키워드 매개 변수(**kwargs)를 받아들인다.모든 신호 처리기는 반드시 이 매개 변수를 받아들여야 한다.
    그러나 매번 값을 받을 때마다 Kwargs에서 꺼내야 하기 때문에 가독성도 떨어지는 것 같다.개인 사용법은 함수에서 자주 사용하는 매개 변수를 직접 열거하는 것이다. 예를 들어 다음과 같다.
    def my_callback(sender, instance, created, **kwargs):
        pass
    

    다음에 해야 할 일은receiver를 signal에 연결하는 것입니다. 수신기를 신호에 연결하는 두 가지 방법이 있습니다.
  • 수동 연결:
  • from django.core.signals import request_finished
    
    request_finished.connect(my_callback)
    
  • receiver 장식기로 자동 연결:
  • receiver(signal)
        Parameters: signal – A signal or a list of signals to connect a function to.​
    
    from django.core.signals import request_finished
    from django.dispatch import receiver
    
    @receiver(request_finished)
    def my_callback(sender, **kwargs):
        print "Request finished!"
    

    지금, 우리 my콜백 함수는 요청이 끝날 때마다 호출됩니다.이렇게 설정하면 각종signals에서 보내는 알림을 받을 수 있습니다.그런데 만약에 제 리셋 함수가 특정sender에만 관심이 있다면 어떡하죠?connect 함수의 sender 매개 변수를 지정하여 필터링할 수 있습니다.
    Signal.connect(receiver[, sender=None, weak=True, dispatch_uid=None])
        Parameters: 
            receiver –             
            sender –         sender,         
            weak – Django              。    ,     receiver       ,        。        connect()   ,   weak=False       
            dispatch_uid –      receiver       ,        ,        ​ 
    

    데코레이터를 사용하여 필터링하기
    from django.db.models.signals import pre_save
    from django.dispatch import receiver
    from myapp.models import MyModel
    
    
    @receiver(pre_save, sender=MyModel)
    def my_handler(sender, **kwargs):
        ... 
    

    my_handler 함수는 MyModel 인스턴스가 저장될 때만 호출됩니다.
    신호를 보내다
    Django에서는 두 가지 방법으로 신호를 보냅니다.
    Signal.send(sender, **kwargs)
    
    Signal.send_robust(sender, **kwargs)
    

    Signal을 호출합니다.send () 또는 Signal.send_robust () 로 신호를 보냅니다.sender 파라미터를 제공해야 합니다. (대부분의 경우 클래스입니다.) 그리고 가능한 한 많은 키워드 파라미터를 제공할 수 있습니다.
    예를 들면, 이렇게 우리 피자를 보내주세요done 신호:
    class PizzaStore(object):
        ...
    
        def send_pizza(self, toppings, size):
            pizza_done.send(sender=self.__class__, toppings=toppings, size=size)
            ...
    

    send() 및 sendrobust () 는 이원조를 포함하는 목록을 되돌려줍니다. [(receiver,response),...]그것은 호출된 수신기 함수와 그들의 응답 값을 대표한다.
    send()와 sendrobust ()는receiver 함수에서 발생하는 이상을 처리할 때 다릅니다.send () 는receiver에서 발생하는 이상을 포착하지 않습니다.그것은 간단하게 잘못을 위로 전달할 것이다.그래서 오류가 발생하는 경우 모든receiver가 알림을 받지 않습니다.
    send_robust () 는 Python Exception 클래스에서 계승된 모든 이상을 포착하고, 모든 receiver가 신호에 대한 알림을 받을 수 있도록 합니다.오류가 발생하면 오류가 발생하는receiver의 이원조에서 오류가 발생합니다.
    인터럽트 시그널
    Signal.disconnect([receiver=None, sender=None, weak=True, dispatch_uid=None])
    

    Signal을 호출합니다.disconnect () 로 신호의 수신기를 끊습니다.Signal.connect () 에서 모든 인자를 설명합니다.수신기가 성공적으로 분리되면 True로 돌아가고 그렇지 않으면 False로 돌아갑니다.
    receiver 매개 변수는 끊을 등록된receiver를 표시합니다.dispatch를 사용하는 경우uid 는 receiver 를 식별하며 None 이 될 수 있습니다.

    좋은 웹페이지 즐겨찾기