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