int*_*_32 17 python django django-signals django-models
我已经阅读了所有相关问题.
我有两个Django项目,信号在一个工作正常,但不在第二个工作(我只是分别复制粘贴代码和更改名称).
我有订单模型的订单应用程序.应用程序包含在INSTALLED_APPS设置中.
我在apps.py中有app配置:
from django.apps import AppConfig
class OrdersConfig(AppConfig):
name = 'orders'
def ready(self):
super(OrdersConfig, self).ready()
# noinspection PyUnresolvedReferences
import signals
Run Code Online (Sandbox Code Playgroud)
__init__.py:
default_app_config = 'orders.apps.OrdersConfig'
Run Code Online (Sandbox Code Playgroud)
最后,signals.py:
@receiver(post_save, sender=Order)
def order_save(sender, instance, created, **kwargs):
print 'Post save'
if created:
print 'Created'
send_email_new_order.delay(settings.MODERATOR_EMAIL, instance.pk)
Run Code Online (Sandbox Code Playgroud)
信号没有被调用.为什么?
Django 1.10.3.
e4c*_*4c5 21
文档说的内容:在save方法的最后.
它的真正含义:在成功完成保存方法的最后.
save方法未成功保存对象(例如IntegrityError发生时)MyModel.objects.update()save方法并忘记调用超类方法时.最简单的是@receiver像你一样使用装饰器.另一种方法是使用
from django.db.models.signals import pre_save
pre_save.connect(order_save, sender='app_label.MyModel')
Run Code Online (Sandbox Code Playgroud)
如今,手册指出了这一点
严格地说,信号处理和注册代码可以在任何你喜欢的地方生活,尽管建议避免应用程序的根模块及其模型模块,以尽量减少导入代码的副作用.
这可能就是为什么在这种情况下你创建了一个名为signals.py的文件,并将你的代码置于其中,然后使用AppConfig类和ready方法解决了所有问题.但有趣的是,Django 1.6手册说:
您可以将信号处理和注册码放在任何您喜欢的地方.但是,您需要确保早期导入模块,以便在需要发送任何信号之前注册信号处理.这使您的应用程序的models.py成为放置信号处理程序注册的好地方.
因此,如果您在注册信号接收器时遇到问题,您实际上可以尝试将代码放入models.py或views.py放弃AppConfig中的位(甚至可能完全删除AppConfig)
如果您想在AppConfig中进行注册,而您在使用@reciever和/或导入时遇到问题,可以试试
from django.db.models.signals import pre_save
from app_label.signals import my_reciever
def ready(self):
pre_save.connect(my_reciever, sender='app_label.MyModel')
Run Code Online (Sandbox Code Playgroud)
信号被触发两次吗?确保只注册一次接收器.如果您注册AppConfig,请将其保留,models.py并将其删除
您绝对确定正确signals的进口吗?(print('hi, signals here')在模块中?)
您可能还想使用绝对限定的import(import orders.signals)或相对的import()import .signals as signals。
| 归档时间: |
|
| 查看次数: |
7537 次 |
| 最近记录: |