django的信号使用疑问

我想在模型保存和删除数据时候进行一些其他操作。
查看文档,模型的保存可以重写。类似如下

models.py

class owgameserver(models.Model):
    serverid = models.IntegerField(u"游戏服ID号",primary_key=True)
    serverhost = models.GenericIPAddressField(u"游戏服IP")
    servername = models.CharField(u"游戏服名称",max_length=32)
    serverport = models.IntegerField(u"游戏服端口号")

    def save(self,*args,**kwargs):
        print '添加新服:服id:%s-服ip:%s-服名称:%s-服端口:%s' %(self.serverid,self.serverhost,self.servername,self.serverport)
        super(owgameserver,self).save(*args,**kwargs)
        print ansible_owgameserver_file
        ansiblefile = open(ansible_owgameserver_file,'a')
        ansiblefile.write('ow%s ansible_ssh_host=%s server_port=%s server_id=%s' %(self.serverid,self.serverhost,self.serverport,self.serverid))
        ansiblefile.close()
        print '添加完成.'

然后想写删除时候,发现文档是提供了信号来处理
然后我的处理如下
single.py

from models import owgameserver
from django.dispatch import receiver
from django.db.models.signals import post_delete,post_save


def del_ansible_host(sender,**kwargs):
    print '删除文件中的列表'
post_delete.connect(del_ansible_host,sender=owgameserver)


def save_ansible_host(sender,**kwargs):
    print '保存内容'
post_save.connect(save_ansible_host,sender=owgameserver)

然后发现,无论我是添加新的内容,还是删除内容都无法触发这两个信号里的内容,这是为咋的?

阅读 3.9k
3 个回答

已自行解决,参考@小杰控的,和stackoverflow一些信息

使用信号后,调用pre_delete,post_save来触发models保存和删除后执行的一些操作

查看文档,在django 1.7后,使用信号时候需要在应用配置类中的ready() 方法中连接。

所以我们需要配置先ready()
需要在以下两个地方写入配置
需要在项目的app.py,__init__.py两个文件中写入配置

app.py中的内容
class OwgameConfig(AppConfig):
    name = 'owgame'

    ####添加ready函数
    def ready(self):
        import owgame.signals  ###项目的signals位置
__init__.py中的内容
default_app_config = 'owgame.apps.OwgameConfig'

###OwgameConfig是app.py中的定义的class类名
signals中的内容
from models import owgameserver
from django.dispatch import receiver,Signal
from django.db.models.signals import post_delete,post_save,pre_save,pre_delete


@receiver(pre_delete,sender=owgameserver)
def del_ansible_host(sender,instance,**kwargs):
    delserver = owgameserver.objects.filter(pk=instance.serverid)
    print u'删除%s,%s' %(delserver[0].servername,delserver[0].serverhost)
    print u'删除文件中的列表'


@receiver(post_save,sender=owgameserver)
def save_ansible_host(sender,instance,**kwargs):
    addserver = owgameserver.objects.filter(pk=instance.serverid)
    print u'添加:%s,%s' %(addserver[0].servername,addserver[0].serverhost)
    print u'保存内容'
测试在添加models和删除models是否会触发这个信号中的内容

添加一个新服

查看日志输出

[28/Oct/2016 15:51:46] "GET /admin/owgame/owgameserver/ HTTP/1.1" 200 7172
[28/Oct/2016 15:51:46] "GET /admin/jsi18n/ HTTP/1.1" 200 3217
[28/Oct/2016 15:51:48] "GET /admin/owgame/owgameserver/add/ HTTP/1.1" 200 5355
[28/Oct/2016 15:51:48] "GET /admin/jsi18n/ HTTP/1.1" 200 3217
添加新服:服id:7-服ip:192.168.12.23-服名称:7服-服端口:8007
添加:7服,192.168.12.23
保存内容

已触发到保存的信号。

删除一个服

查看输出日志

[28/Oct/2016 15:54:27] "GET /admin/owgame/owgameserver/7/change/ HTTP/1.1" 200 5632
[28/Oct/2016 15:54:27] "GET /admin/jsi18n/ HTTP/1.1" 200 3217
[28/Oct/2016 15:54:31] "GET /admin/owgame/owgameserver/7/delete/ HTTP/1.1" 200 3035
删除7服,192.168.12.23
删除文件中的列表
[28/Oct/2016 15:54:43] "POST /admin/owgame/owgameserver/7/delete/ HTTP/1.1" 302 0
[28/Oct/2016 15:54:44] "GET /admin/owgame/owgameserver/ HTTP/1.1" 200 7323
[28/Oct/2016 15:54:44] "GET /admin/jsi18n/ HTTP/1.1" 200 3217

已触发删除信息。

clipboard.png

在实操中,sigal handler写在signals模块下面。

然后需要在app的ready()方法中引用这些handlers。

首先,先确保你的single.py 有被import过,这样django才能读取到你里面的注册的signals.

post_save 顾名思义,是在save操作之后触发。也即当你调用 model.save(),执行保存后触发。update方法不会触犯该signals.

post_delete,是在delete操作之后触发。也就是当你调用model.delete(),model删除后才会触发。.filter().delete() 不会触发该signals.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏