Skip to main content
 首页 » 编程设计

python之Django 信号 : How to initialize bindings

2025年05月04日39Renyi-Fan

我正在应用程序的 __init__.py 文件中导入信号文件。问题发生在我运行 manage.py runserver 时,我发现 __init__.py 被导入了两次,并且我的回调运行了两次。

但是,当我运行 manage.py shell 时,__init__.py 按预期工作(一次)

(Django 1.8.3)

app/__init__.py:

print 'Hello!' 
import signals 

应用程序/模型.py:

from django.db import models 
 
class RemoteTask(models.Model): 
    title = models.CharField(max_length=50) 
 
class RemoteTaskStatus(models.Model): 
    remote_task = models.IntegerField() 
    status = models.IntegerField() 

应用程序/信号.py:

print '------> app/signals.py' 
 
from django.db.models.signals import post_save 
from django.dispatch import receiver 
from app.models import RemoteTask, RemoteTaskStatus 
 
@receiver(post_save, sender=RemoteTask) 
def status_new(sender, **kwargs): 
    print '---------> Running callback' 
    if kwargs.get('created', 'False') is True: 
        instance = kwargs['instance'] 
        RemoteTaskStatus.objects.create( 
            remote_task=instance, 
            status=0 
        ) 

示例输出:

$ ./manage.py runserver 
Hello! 
------> app/signals.py 
Hello! 
------> app/signals.py 
Performing system checks... 
 
System check identified no issues (0 silenced). 
August 12, 2015 - 19:50:38 
Django version 1.8.3, using settings 'signal_loca.settings' 
Starting development server at http://127.0.0.1:8000/ 
Quit the server with CONTROL-C. 

Angel Velasquez 的解决方案: app/__init__.py:

print 'Hello!' 
import app.signals 

请您参考如下方法:

在 AppConfig.ready 方法中导入您的 signals.py 以防止回调被注册两次。以下是执行此操作的推荐方法:

my_awesome_project/ 
|-- app/ 
|   |-- __init__.py   <-- set default_app_config here 
|   |-- apps.py       <-- define your AppConfig subclass here 
|   |-- models.py 
|   |-- signals.py    <-- define your signal handling functions here 
|-- other_app/ 
|-- my_awesome_project/ 
    |-- __init__.py 
    |-- settings.py 
    |-- wsgi.py 

app/__init__.py

default_app_config = 'app.apps.MyAppConfig' 

app/apps.py

from django.apps import AppConfig 
 
class MyAppConfig(AppConfig): 
    name="app" 
 
    def ready(self): 
        from . import signals 

apps/models.py

from django.db import models 
 
class RemoteTask(models.Model): 
    title = models.CharField(max_length=50) 
 
class RemoteTaskStatus(models.Model): 
    remote_task = models.IntegerField() 
    status = models.IntegerField() 

app/signals.py

from django.db.models.signals import post_save 
from django.dispatch import receiver 
from app.models import RemoteTask, RemoteTaskStatus 
 
@receiver(post_save, sender=RemoteTask, dispatch_uid="status_new_signal_on_RemoteTask_post_save") 
def status_new(sender, **kwargs): 
    print '---------> Running callback' 
    if kwargs.get('created', 'False') is True: 
        instance = kwargs['instance'] 
        RemoteTaskStatus.objects.create( 
            remote_task=instance, 
            status=0 
        ) 

编辑:

添加 dispatch_uid 到 receiver 装饰器。