Django中的信号使用

信号

Django包括一个“信号分配器”,它帮助允许解耦应用程序在框架中其他地方发生操作时得到通知。简而言之,信号允许某些 senders 通知一组 receivers 已经发生了一些行动。当许多代码可能对同一事件感兴趣时,它们特别有用。

Django提供了一些内置信号,让用户代码由Django本身通知某些操作。这些包括一些有用的通知:

  • django.db.models.signals.pre_save&django.db.models.signals.post_save
    在模型的 save() 方法被调用之前或之后发送。
  • django.db.models.signals.pre_delete&django.db.models.signals.post_delete
    在模型的 delete() 方法或查询集的 delete() 方法被调用之前或之后发送。
  • django.db.models.signals.m2m_changed
    模型上的 ManyToManyField 更改时发送。
  • django.core.signals.request_started&django.core.signals.request_finished
    当Django启动或完成HTTP请求时发送。

完整的内置信号可以参考文档:https://www.rddoc.com/doc/Django/1.10.5/zh/ref/signals/

今天我们重点学习pre_savepost_save这两个内置信号。

pre_save

django.db.models.signals.pre_save 这个信号是在模型的 save()方法执行之前调用的。我们看看随着信号一起发送的参数:

sender
1
模型类
instance
1
正在保存的实际实例
raw
1
A boolean; True if the model is saved exactly as presented (i.e. when loading a fixture). One should not query/modify other records in the database as the database might not be in a consistent state yet.
using
1
正在使用的数据库别名。
update_fields
1
要传送到 Model.save() 时要更新的字段集,如果 update_fields 未传递给 save(),则为 None。

实际代码输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from django.dispatch import Signal, receiver
from django.db.models.signals import post_save

from models import PersonInfo

@receiver(post_save, sender=PersonInfo, dispatch_uid='zheshiyiciceshi')
def post_test(sender, **kwargs):
print(sender)
print(kwargs)
return True


if __name__ == '__main__':
one_person = PersonInfo.objects.get(pk='77')

one_person.name = '小吴'
one_person.save()

# 输出
<class 'personmanage.models.models.PersonInfo'>
{'signal': <django.db.models.signals.ModelSignal object at 0x105c239b0>, 'using': 'default', 'created': False, 'instance': <PersonInfo: PersonInfo object>, 'update_fields': None, 'raw': False}

这里我们使用装饰器注册信号(稍后会学到),使用sender指定模型,若是不指定模型则是在任何模型调用过save()方法后都会调用该信号,我想这也不是我们期望的。

post_save

django.db.models.signals.post_save 这个信号是在模型的 save()方法执行之后调用的。我们看看随着信号一起发送的参数:

sender
1
模型类。
instance
1
正在保存的实际实例。
created
1
布尔值; True,如果创建了新记录。
raw
1
布尔值; True,如果模型完全按提供的方式保存。不应该查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态。
using
1
正在使用的数据库别名。
update_fields
1
要传送到 Model.save() 时要更新的字段集,如果 update_fields 未传递给 save(),则为 None。

参考文章:

https://www.cnblogs.com/renpingsheng/p/7566647.html

http://www.liujiangblog.com/course/django/170

https://www.rddoc.com/doc/Django/1.10.5/zh/topics/signals/

知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!