Simple Usage of Signal signals in Django

  • 2021-07-09 08:44:47
  • OfStack

Text

In the normal development process, we will encounter a special application scenario. If you want to be notified before or after performing a certain operation and do something you want, you can use the signal in Django (signals). Django provides a "signal distributor", which allows decoupled applications to be notified when operations occur elsewhere in the framework, that is to say, when a specific event occurs, a signal can be sent to inform all callbacks registered with this signal, and the desired operation processing can be carried out in the callback.

1. Django built-in signal

Django has built-in five kinds of signals: data table, migrate command, url request correlation (request/response), test test and database connection.


Model signals
 pre_init   # model Trigger before executing the constructor 
 post_init   # model Triggers after the constructor is executed 
 pre_save   # model Execute save Trigger before saving the object 
 post_save   # model Execute save Trigger before saving the object 
 pre_delete   # model Execute delete Triggered before the object is deleted 
 post_delete   # model Execute delete Triggered before the object is deleted 
 m2m_changed   # model Using many-to-many fields to manipulate the 3 Before and after the table is drawn, trigger 
 class_prepared  #  When the program starts, detect the registered model Class, for each class, triggers 

Management signals
 pre_migrate   #  Execute migrate Before, trigger 
 post_migrate   #  Execute migrate Triggered after 

Request/response signals
 request_started  #  Trigger before the request arrives 
 request_finished  #  Trigger after the request ends 
 got_request_exception #  Triggered after an exception is requested 

Test signals
 setting_changed  #  Use test Test modifies the configuration file, triggering 
 template_rendered  #  Use test Triggered when the rendering template is tested 

Database Wrappers
 connection_created  #  Triggered when a database connection is created 

1. Introduction of commonly used built-in signal parameters

(1)django.db.models.signals.pre_save

Parameter introduction of pre_save handler

Parameter name parameter introduction
sender model class
Actual instance saved by instance (saved model data object)
raw Boolean value; True If the model is saved exactly as provided. You should not query/modify other records in the database, because the database may not be in the 1-to-1 state yet
Database alias being used by using
update_fields to pass to the updated field set model. save (), or None if update_fields is not passed to it save ()

(2)django.db.models.signals.post_save

Parameter introduction of post_save handler

Parameter name parameter introduction
sender model class
Actual examples saved by instance
created Boolean value; True If a new record is created (True for data creation)
raw Boolean; True If the model is saved exactly as provided. You should not query/modify other records in the database, because the database may not be in the 1-to-1 state yet
Database alias being used by using
update_fields to pass to the updated field set model. save (), or None if update_fields is not passed to it save ()

(3)django.db.models.signals.pre_delete

Parameter introduction of pre_delete handler

Parameter name parameter introduction
sender model class
instance Actual Instance to Delete
Database alias being used by using

(4)django.db.models.signals.post_delete

Parameter introduction of post_delete handler

Parameter name parameter introduction
sender model class
The actual instance of instance to delete (this object will no longer exist in the database, so treat this instance with caution)
Database alias being used by using

Please refer to https://docs.djangoproject.com/zh-hans/2.1/ref/signals/ for more information on signal parameters

2. Built-in signal monitoring method

For Django built-in signal, only need to register the specified signal, when the program executes the corresponding operation, automatically trigger the registration function. When you write a receiver (receiver function) for callback processing after receiving the signal, you need to connect the receiver to the signal in two ways, manually, and using receiver decorator.

Manual connection implementation method:


from django.db.models.signals import post_delete

def my_callback(sender, **kwargs):
 print(sender)
 print(" Signal received ")

post_delete.connect(my_callback) #  The signal is connected to the receiver for callback of the received signal , If you want to specify a table object, specify the sender

# connect Parameter reception 
"""
receiver -  The callback function that will be connected to this signal. Callback function name, without parentheses 
sender -  Specifies the specific sender from which the signal is received. 
weak - Django The signal handler is stored as a weak reference by default. Therefore, if your sink is a local feature, it may be garbage collected. To prevent this, please weak=False In the call signal connect() Method is passed when the. 
dispatch_uid -  In the case that it is possible to send repetitive signals, the only one of the signal receivers 1 Identifier. 
"""

Implementation method of receiver decorator:


from django.dispatch import receiver
from django.db.models.signals import post_delete
from app.models import UCenter

@receiver(post_delete, sender=UCenter) # post_delete Specifies the type of signal trigger, sender Specify to a concrete object 
def delete_u2user(sender, instance, **kwargs): # instance Represents the deleted object 
 print(sender, instance)

Refer to document https://docs.djangoproject.com/zh-hans/2.1/topics/signals/ for more issues related to signal operation

2. Customize signal usage

STEP 1 Define the signal


from django.dispatch import Signal

test_signal = Signal(providing_args=["name", "age"]) #  Declaration 1 A test_signal The signal is provided to the receiver name Follow age Two parameters (customizable parameters) 

2. Register signal


def my_callback(sender, **kwargs):
 print(sender)
 print(" Signal received ")

test_signal.connect ( my_callback )  #  Register signal specifying the receiver as my_callback

3. Trigger signal


from xxx import test_signal

test_signal.send(sender='test', name='zzq', age='18') #  Trigger signal, send name , age Parameter information 

Of course, there are two ways to choose to send signals. One is Signal.send, and the other is Signal.send_robut.

send () and send_robust () handle exceptions caused by receiver functionality differently.

send () does not catch any exceptions raised by the receiver; It just allows errors to spread. Therefore, not all receivers can be notified of the signal in the face of errors.

send_robust () captures all errors derived from the Python Exception class and ensures that all sinks are signaled. If an error occurs, the error instance is returned in the tuple pair of the sink that raised the error.

Summarize


Related articles: