Django当DEBUG = False时,信号不触发问题

今天突然发现生产环境中,某些信号没有被正确触发,一番调查总结一下关于django信号执行问题。

先看一个现象:

python 复制代码
# host/signals.py
@receiver(m2m_changed, sender=Vm.products.through)
def on_m2m_changed(sender, instance, action, pk_set, **kwargs):
    do something


@receiver(m2m_changed, sender=Vm.tags.through)
def on_m2m_changed(sender, instance, action, pk_set, **kwargs):
    do something


DEBUG=True时:
当修改Vm.products.through表时,第一个信号可以正常被触发,没什么问题
当修改Vm.tags.through表时,第二个信号可以正常被触发,也没什么问题
DEBUG=False时:
当修改Vm.products.through表时,第一个信号不能被正确触发
当修改Vm.tags.through表时,第二个信号可以正常被触发,没什么问题

也就是说是否开启debug模式会影响第一个信号的触发,查了下官方文档发现:

警告

还需要注意的是,Django 默认将信号处理程序存储为弱引用,所以如果你的处理程序是一个本地函数,它可能会被垃圾回收。 为了防止这种情况,当你调用信号的 connect() 时,传入 weak=False

然后尝试传入weak=False,果然信号被正确触发了。看来真的如文档所说的一样,第一个信号处理函数被垃圾回收了。

那不对啊,项目中其他用到信号的地方也没加weak参数,也没发现这种信号不被触发的问题。

回头看看,发现我这两个多对多信号处理函数名称相同了,尝试换了不一样的函数名,即使不使用weak参数,两个信号处理函数也能被正确触发。

至此问题已清晰明了,是因为两个信号处理函数同名了,导致第一个被垃圾回收了。

总结:

同一个文件中的信号处理函数名称不能一样,否则靠前的函数会被垃圾回收,除非传入weak=False参数声明为强引用。

相关推荐
千里码aicood6 小时前
基于Python的电商数据采集系统(大数据+爬虫)
开发语言·python
boooooooom6 小时前
尝尝咸淡:从朴素 RAG 到 Graph RAG——一个烹饪问答系统的三层检索升级之路
前端·后端·llm
战略性的菠萝6 小时前
研究生基础-Python快速入门(终)——面向对象
python
陈皮波比茶6 小时前
Python项目实战-网络机器人(爬虫)
开发语言·网络·爬虫·python·机器人
winfredzhang7 小时前
从零构建家庭照片管理系统:Django 模块化单体实战,以及我踩到的 4 个真实坑
python·postgresql·django·sqlite·bootsrap
jyOverQ7 小时前
LangGraph 流式执行详解:stream、astream 与 stream_mode 怎么选?
python·langchain
2601_963870187 小时前
【计算机毕业设计】基于Vue+Spring Boot的助农电商系统的设计与实现
spring boot·后端·课程设计
sun༒7 小时前
Spring @Scheduled 定时任务详解:Cron表达式、执行顺序、优先级与并行调度
java·后端·spring
闲猫7 小时前
LangGraph / Capabilities / Stores
python·agent·langgraph
yuhaiqiang7 小时前
从这两件事就能看出 vibecoding 距离专业作品差距有多大?AI 能抹平技术,但抹不平品味 !
前端·后端·程序员