写点什么

Django 的 Models 更新时,不触发 Signals 解决办法

用户头像
Young先生
关注
发布于: 2020 年 08 月 14 日
Django的Models更新时,不触发Signals解决办法

django的信号机制Signals



当指定的models变化时,能够触发django的Signals机制。这样我们就可以针对models变化做对应的操作。

简单的使用文档:https://www.cnblogs.com/fiona-zhong/p/9983996.html



原来的代码



models.py
class User(models.Model):
username = models.CharField(max_length=255, unique=True, verbose_name='用户名')
mobile = models.CharField(max_length=255, verbose_name='手机号')
is_active = models.BooleanField(default=False, verbose_name='激活状态')



views.py
user_attr = {
mobile="1234567890",
is_active=True
}
User.objects.filter(id=1).update(**user_attr)

然后我通过Signals机制,监控字段is_active是否改为True,然后触发一些动作

@receiver(signals.post_save, sender=User)
def migrate_user_modify(instance, created, **kwargs): # created:新建数据时是True,更新是False
if not created and instance.is_active == True:
do someting

遇到的问题

本以为views.py中的代码执行后,会触发Signals机制,然后do something,但是实际没有任何动作。



解决办法

修改views.py中的数据更新方法。改为:

方式一:

_t = User.objects.get(id=1)
_t.mobile='1234567890'
_t.is_active=True
_t.save()

方式二:

user_attr = {
mobile="1234567890",
is_active=True
}
_t = User.objects.get(id=1)
_t.__dict__.update(**user_attr)
_t.save()



原因

因为这种形式:User.objects.filter(id=1).update(**user_attr),Django直接更新的数据库,没有经过models,所以不会触发Signals机制。

官方文档有解释:https://docs.djangoproject.com/zh-hans/2.2/topics/db/queries/ ,搜索"要认识到 update() 方法是直接转为 SQL 语句的",后边明确写有。



知道了原因,我们就针对修改为上边的两种更新方式就可以了。



参考文档:

官方文档:https://docs.djangoproject.com/zh-hans/2.2/topics/db/queries/

Django model update的各种用法介绍:https://juejin.im/post/5b588b656fb9a04fba6e8681



本文首发于BigYoung小站http://www.bigyoung.cn

发布于: 2020 年 08 月 14 日阅读数: 68
用户头像

Young先生

关注

Python工程师/书虫/极客/ 2020.04.22 加入

伸手摘星,即使徒劳无功,也不至于满手泥污。 欢迎大家访问我的BigYoung小站(bigyoung.cn)

评论

发布
暂无评论
Django的Models更新时,不触发Signals解决办法