[Reprinted] Use signals to monitor the changes in the Django model object field value, django Field
Reprinted Source: http://blog.csdn.net/pushiqiang/article/details/74949465
The function of the Django signal (Signals) is similar to the action of WordPress. It is used to add a global event broadcast (dispatch) and receive (receive) mechanism for the project. Among them, the flexible use of its built-in Model signal reception function can monitor the changes of most Model Objects (Model instances. Because you do not need to modify the model code, it has the advantage of low coupling for cross-application (App) monitoring.
Basic usage
The topic and reference of the official document on the basic usage of signals have been described in detail. This article only mentions a few key points (Environment: Django 1.8 & Python 3.4 ):
Code Organization
It is officially recommended to addsignals.py
File, and refer to the application configuration section of the official documentation to customize the application configuration (AppConfig), reload the application configuration classrun
Method, called in this methodfrom . import signals
Receive Signal
Recommendeddjango.dispatch.receiver
This decorator receives signals:
from django.db.models import signalsfrom django.dispatch import receiverfrom students.models import Studentfrom .models import Announcement@receiver(signals.post_save, sender=Student)def welcome_student(instance, created, **kwargs): if created: Announcement.objects.create(content='Welcome new student ' + instance.name)
From the perspective of code readability, it is recommended that a receiving function do only one thing.
Monitor changes in specific field values
As you can see from the previous Code, by receiving the Modelpost_save
Signal, you can know that the operation to save the model object has occurred, and you can also distinguish whether the model object is created or updated. However, the model signal does not provide the Broadcast Function for specific field value changes, although the signal providesupdate_fields
Parameter, but it does not prove that the field value of the field name in this parameter must have changed, so we need to use a combinationpost_init
Signal work und.
For example, an announcement is published when the student name changes.
from django.db.models import signalsfrom django.dispatch import receiverfrom students.models import Studentfrom .models import Announcement@receiver(signals.post_init, sender=Student)def welcome_student(instance, **kwargs): instance.__original_name = instance.name@receiver(signals.post_save, sender=Student)def welcome_student(instance, created, **kwargs): if not created and instance.__original_name != instance.name: Announcement.objects.create(content= 'Student %s has renamed to %s' % (instance.__original_name, instance.name))
Simply put, broadcast in this modelpost_init
When the signal is sent, the current field value is cached in the model object.post_save
(Orpre_save
), Compare the current field value of the model object with the cached field value. If they are different, the field value changes.