Program decoupling of good works, django semaphore

 

Built-in signal is easy to use

1. From a http request to start

First, we need to write a py file for receiving signals in the app, may wish to file named: signal_test.py.

One way to use the following received signal

  •  method one
from django.core.signals import request_finished
def my_callback(sender, **kwargs):
    print("Request finished!")
request_finished.connect(my_callback)
  •  Second way
from django.core.signals import request_finished
@receiver(request_finished)
def my_callback(sender, **kwargs):
    print("Request finished!")

 

 In apps.py file in the current app by AppConfig subclass, override the ready function, before introduction of the ready signal function receives the file signal_test.py, for example: now my app called app name, then AppConfig subclass as follows:

from django.apps import AppConfig
class AppConfig(AppConfig):
    name = 'app'
    def ready(self):
        from . import signal_test

 

Then ensure the app settings are installed in the following format:

INSTALLED_APPS = [
    '……',
    'app.apps.AppConfig'
]

 

If you write directly in INSTALLED_APPS "app", then it will lead to the signal can not be received properly, please note.

Write a simple view function, such as:

def signal_control(request):
    return HttpResponse("hello world")

Access to the view interface upon completion of the request can see the information printed in the receiver signal, thus completing the simple use of the built signal django

 

2. The kind of built-in signal

django version 2.1.4 is used herein, in earlier versions, module position where the signal may be somewhat different.

  • django.db.models.signals
pre_init        # before django of modal execute its constructor, automatically triggering 
post_init       # after modal django execution of its constructor, automatically trigger 
pre_save        # before modal object holds django automatically trigger 
post_save       # after django of modal objects saved automatically trigger 
pre_delete      # django before the modal object deletion, automatic trigger 
post_delete     # after modal objects django deleted automatically trigger 
m2m_changed     # before and after the modal django used in the m2m field operation the third table (add, remove, clear), automatically trigger 
pre_migrate     # execute migrate command ago, triggered automatically 
post_migrate    # after executing migrate command, automatically triggers
  • django.core.signals
request_started          # request before arrival, triggered automatically 
request_finished         # after the end of the request, automatically triggered 
got_request_exception    # After requesting an exception, automatically trigger 
setting_changed          # when the changes to the configuration file, automatically trigger
  • django.test.signals
template_rendered    # Use test test rendering templates, automatically trigger
  • django.db.backends.signals
connection_created    # When you create a database connection, automatically trigger

 

3. Detailed built-in signal

From a dome, we found the request_finished signal is not sent to any of the parameters, despite this, the signal receiver is still required parameters ** kwargs, otherwise it will django error, please note.

For pre_save and post_save signal, regular demand before processing business, you need to check is the "new" or "updated", we both do a comparison, ** kwargs parameters are as follows:

# 新增
{
    'signal': <django.db.models.signals.ModelSignal object at 0x000002A1A16ADFD0>,
    'instance': <User: User object (None)>,
    'raw': False,
    'using': 'default',
    'update_fields': None
 }
# 修改
{
    'signal': <django.db.models.signals.ModelSignal object at 0x000002399970DFD0>, 
    'instance': <User: User object (1)>, 
    'raw': False, 
    'using': 'default', 
    'update_fields': None
}

There is a very strange reason, whether pre_save or post_save, even if modify the model, print out update_fields still None, for pre_save, can be distinguished by instance, and for post_save, ** kwargs will add a new parameter Created (if new, the value is False; if modified, the value True)

 

Learn more signal

1. Signal monitor

To receive signal is a need to register the listener for receiving a signal by using Signal.connect () to listen, and then write a function for processing signals, connect through the receiver parameter to point to the reference function. A description of each parameter Signal.connect do the analysis:

Signal.connect (Receiver [, sender = None, weak = True, dispatch_uid = None]) 
    Receiver: callback processing signals 
    sender: specifies a particular sender, the received signal from a particular sender is 
    weak:          
           the Django generally weak reference stored signal processor. This means that if your receiver is a Bureau of
           the Ministry of variables, might be garbage. When you call connect signal () method, passing weak
= False to prevent doing so. dispatch_uid: unique identifier of the receiver, multiple transmission signals to prevent, to prevent the reference signal is repeated.

 

2. duplicate preventing signal

In some cases, the code signal receiver is connected may be performed multiple times. This will make your receiver function is registered multiple times and cause it to signal the same event is called multiple times. First, we need to confirm whether this case is unnecessary, if necessary, should be given that the use of Signal.connect parameters dispatch_uid when receiving signals. dispatch_uid hash object may be, but usually is a unique string.

 

3. Disconnect the signal

Currently this is not very common, if necessary you can call Signal.disconnect () to disconnect the receiver signal. Signal.connect () is described in all the parameters. If the receiver is disconnected successfully return True, otherwise False. To disconnect the receiver parameter indicates the registered receiver. If you use dispatch_uid identification receiver, it may be None.

 

4. Custom signal

Customize signal provided by Django is also very simple. It consists of the following steps

(1) the definition of a signal

Django provides all signal instances (i.e. django.dispatch.Signal), the user needs to provide a parameter providing_args django.dispatch.Signal, the type of the parameter list, providing_args each cell is provided to a recipient parameter signal . For example: pizza_done toppings and size parameters to provide a signal to the recipient

(2) a transmission signal

Send a signal in two ways, namely:
  Signal.send (sender, ** kwargs)
  Signal.send_robust (sender, ** kwargs)
  when transmitting a signal, we must provide parameters that sender, if the previous definition signal there parameters toppings and size,

  It is also desirable to provide, sender is a general class parameters (so to facilitate signal reception)

 send () and send_robust () returns a list of tuples containing [(receiver, response), ...], which represents the function of the receiver is called and their response. send () and send_robust () differ receiver processing function abnormality generated. send () will not catch any exceptions generated by the receiver. It will simply let the error pass up. So be notified in case of an error generated will not all receiver. send_robust () to capture all inherited abnormal Python Exception class of self, and to ensure that all have access to the notification signal receiver. If an error occurs, the error will return an instance of the tuple error in the receiver.

(3) the received signal

Signal.connect way of using the previous example, are mostly used to accept signals, but we generally use @receiver a little more.

@receiver (pizza_done, SENDER = PizzaStore)
 DEF my_callback (SENDER, ** kwargs):
     Print ( " receives a signal from the PizzaStore " )

 

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/lynn578/p/11870205.html