Django post_syncdb信号处理器未被调用?
我有一个 myapp/management/__init__.py
文件,它在里面注册了一个 post_syncdb
的处理器,像这样:
from django.db.models import signals
from features import models as features
def create_features(app, created_models, verbosity, **kwargs):
print "Creating features!"
# Do stuff...
signals.post_syncdb.connect(create_features, sender=features)
我确认了以下几点:
- 两个应用
features
和myapp
都在settings.INSTALLED_APPS
列表里 myapp.management
在执行 syncdb 之前就已经加载了(我通过在模块级别加了一个打印语句来确认)features
应用在syncdb
处理时被处理,并且它发出了post_syncdb
的信号(我通过查看syncdb
的输出,使用了--verbosity=2
来确认)- 我对另外一对应用使用了完全相同的方式,那个处理器能正常调用。我对比了这两个模块,发现它们在调用上没有相关的区别。
但是,myapp.management.create_features
从来没有被调用。我遗漏了什么呢?
3 个回答
0
关键在于 sender
。你的自定义回调函数只有在 sender
成功执行时才会被调用。在我的情况下,sender
是 db.models
,而当 syncdb
不是第一次调用时,它就不会成功,也就是说,数据库中已经存在同步过的模型。文档里有提到这一点,但没有强调清楚。
sender
刚刚安装的模型模块。也就是说,如果
syncdb
刚刚安装了一个叫 "foo.bar.myapp" 的应用,那么sender
就是 foo.bar.myapp.models 模块。
所以我的解决办法是删除数据库,然后重新安装我的应用。
1
我刚遇到同样的问题,我的解决办法是把函数参数中的 sender
去掉,然后在回调函数里面检查它。
from django.db.models import signals
from features import models as features
def create_features(app, created_models, verbosity, **kwargs):
print "Creating features!"
if app != features #this will work as it compares models module instances
return
# Do stuff...
signals.post_syncdb.connect(create_features)
这样你就可以像Django文档里建议的那样,把它们放在你的管理模块里。我同意你的想法,它应该像你说的那样工作。你可以深入研究一下 django.dispatch
里的 Signal 类的实现。
3
试着把它放到你的 models.py 文件里。