简体   繁体   English

Django pre_save 信号不起作用

[英]Django pre_save signal does not work

I tested the "pre_save" signal of Django in the following ways, but cannot catch the signal in either of them.我通过以下方式测试了 Django 的“pre_save”信号,但无法捕获其中任何一个信号。

$ $

from django.db.models.signals import pre_save
import logging

def my_callback(sender, **kwargs):
    logging.debug("======================================")
pre_save.connect(my_callback)
  1. Run the above code in manage.py shell: Then I run my website and see models.save() work successfully, but the callback function does not run.在 manage.py shell 中运行上面的代码: 然后我运行我的网站,看到 models.save() 工作成功,但是回调 function 没有运行。

  2. Alternatively, I run the above code on shell again and then run models.save() in the shell.或者,我再次在 shell 上运行上述代码,然后在 shell 中运行 models.save()。 "save" works well again but still nothing happens to the callback function. “保存”再次运行良好,但回调 function 仍然没有任何反应。

  3. Finally, I embed the above code in an __init__.py file and still, run the save() function on the website.最后,我将上述代码嵌入到__init__.py文件中,然后在网站上运行 save() function。 Still, nothing occurs.不过,什么也没有发生。

Would you please help me figure out why pre_save signal seems not work?请你帮我弄清楚为什么 pre_save 信号似乎不起作用?

You're not setting the sender class for one.您没有将发件人 class 设置为一个。

from django.db.models.signals import pre_save
from myapp.models import MyModel
import logging

def my_callback(sender, **kwargs):
    logging.debug("======================================")
pre_save.connect(my_callback, sender=MyModel)

Secondly, if you're using Django 1.3 you should use the new decorator syntax.其次,如果您使用的是 Django 1.3,您应该使用新的装饰器语法。

# Inside your models.py
from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver

class MyModel(models.Model):
    field1 = models.TextField()
    field2 = models.IntegerField()

@receiver(pre_save, sender=MyModel)
def mymodel_save_handler(sender, **kwargs):
    logging.debug("======================================")

That should do it, but I haven't tested the code so let me know if it's still broken.那应该可以,但是我还没有测试过代码,所以让我知道它是否仍然损坏。

logging.debug() is using the root logger, which handler level by default is 30 ('WARNING'). logging.debug()使用根记录器,默认情况下处理程序级别为30 ('WARNING')。

=> logging.debug('something') is just not doing anything at all (DEBUG level is 10 < 30). => logging.debug('something')根本没有做任何事情(DEBUG 级别是 10 < 30)。 See http://docs.python.org/2/library/logging.htmlhttp://docs.python.org/2/library/logging.html

The same test should be done with another custom logger, or by doing:应该使用另一个自定义记录器进行相同的测试,或者通过执行以下操作:

l = logging.getLogger()
l.setLevel(10)
def my_callback(sender, **kwargs):
    logging.debug("======================================")
pre_save.connect(my_callback)

The original question is not containing enough info to know if it's the real problem the OP was facing (or part of it).最初的问题没有包含足够的信息来了解这是否是 OP 面临的真正问题(或部分问题)。
But surely the OP's code was not going to work with my ./manage.py shell但可以肯定的是,OP 的代码不适用于我的./manage.py shell

The reason Eric's answer made it work is because he got you to connect the signal inside models.py, so that when you then save the model via your website the signal handler is in the same process as the signal firer. Eric 的回答使它起作用的原因是因为他让您在 models.py 中连接信号,因此当您通过您的网站保存 model 时,信号处理程序与信号触发程序处于同一进程中。

In examples 1 and 3 it's easy to see why they didn't work - you are saving in a different process (the website) to where your signal receivers are listening.在示例 1 和示例 3 中,很容易看出它们为什么不起作用 - 您将保存在与信号接收器正在收听的不同进程(网站)中。

I wish I understood better why example 2 is also broken but I just debugged a similar issue in my own project while testing signals in the shell and it's definitely something to do with signal senders and receivers not being able to 'see' each other.我希望我能更好地理解为什么示例 2 也被破坏了,但我只是在我自己的项目中调试了一个类似的问题,同时在 shell 中测试信号,这绝对与信号发送器和接收器无法“看到”对方有关。

as described in the django signals doc the pre_save signal accept 3 unique arguments (not keyword arguments) so, you need to edit your my_callback function to be as follow:django 信号文档中所述, pre_save信号接受 3 个唯一的 arguments (不是关键字参数),因此,您需要编辑my_callback function 如下:

def my_callback(sender,instance, using, **kwargs):
    logging.debug("======================================")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM