Django信号,实现保存监听器
我在理解信号是怎么工作的方面遇到了一些困难。我看了很多页面,但都没能让我明白这个概念。
我有两个模型,我想创建一个信号,当父模型保存记录时,能够在子模型中保存数据。实际上,我希望这个子模型能够在我的应用程序中监听任何父模型,因为这个子模型是一个通用外键。
core/models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Audit(models.Model):
## TODO: Document
# Polymorphic model using generic relation through DJANGO content type
operation = models.CharField(max_length=40)
operation_at = models.DateTimeField("Operation At", auto_now_add=True)
operation_by = models.ForeignKey(User, db_column="operation_by", related_name="%(app_label)s_%(class)s_y+")
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
workflow/models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from core.models import Audit
class Instances(models.Model):
## TODO: Document
## TODO: Replace id with XXXX-XXXX-XXXX-XXXX
# Re
INSTANCE_STATUS = (
('I', 'In Progress' ),
('C', 'Cancelled' ),
('D', 'Deleted' ),
('P', 'Pending' ),
('O', 'Completed' )
)
id=models.CharField(max_length=200, primary_key=True)
status=models.CharField(max_length=1, choices=INSTANCE_STATUS, db_index=True)
audit_obj=generic.GenericRelation(Audit, editable=False, null=True, blank=True)
def save(self, *args, **kwargs):
# on new records generate a new uuid
if self.id is None or self.id.__len__() is 0:
import uuid
self.id=uuid.uuid4().__str__()
super(Instances, self).save(*args, **kwargs)
class Setup(models.Model):
## TODO: Document
# Polymorphic model using generic relation through DJANGO content type
content_type=models.ForeignKey(ContentType)
object_id=models.PositiveIntegerField()
content_object=generic.GenericForeignKey('content_type', 'object_id')
class Actions(models.Model):
ACTION_TYPE_CHOICES = (
('P', 'Python Script'),
('C', 'Class name'),
)
name=models.CharField(max_length=100)
action_type=models.CharField(max_length=1, choices=ACTION_TYPE_CHOICES)
class Tasks(models.Model):
name=models.CharField(max_length=100)
Instance=models.ForeignKey(Instances)
我在Audit模型中创建监听器时遇到了困难,这样我就可以把它和Instance模型连接起来。如果在Instance中插入了新记录,它会自动在Audit中插入一条记录。接下来,我计划把这个监听器连接到我应用中的多个模型。
有没有人知道我该怎么做呢?
1 个回答
4
下面的代码可以让你把一个实例对象的保存操作和一个叫做 after_save_instance_handler 的方法连接起来。在这个方法里,你可以创建与审计(Audit)的关系。你还可以查看这个 通用关系文档。
我通常会在定义了发送者的 models.py 文件里添加信号(signals)。不太确定这样做是否必要。
from django.db.models.signals import post_save
#####SIGNALS######
def after_save_instance_handler(sender, **kwargs):
#get the saved instance
instance_object = kwargs['instance']
#get the needed data
the_date = ...
the_user = ...
the_object_id = ...
#create the relation to the audit object
instance_object.audit_obj.create(operation="op963",operation_at=the_date,operation_by=the_user,object_id=the_object_id)
#connect the handler with the post save signal - django 1.1 + 1.2
post_save.connect(after_save_instance_handler, sender=Instances)
在 Django 的开发版本中,他们添加了一个装饰器来连接信号。所以,除了上面的调用,你需要把这个装饰器加到处理函数上。
@receiver(post_save, sender=Instances)
def after_save_instance_handler(sender, **kwargs):