3

所以我正在使用 django-simple-history 模块来跟踪模型实例的变化。但是,它使用 post_save 信号来执行此操作。在我的项目中,我还需要它在 update() 上触发。

我的问题是:如何覆盖 update() 方法来触发 post_save 信号?

4

2 回答 2

13

这样做的问题是.update()不必从数据库中加载对象来完成它的工作。考虑一个有 100 万行的 users 表的示例:

users = User.objects.filter(date_joined__lte=now() - timedelta(days=30)
users.update(is_active=False)

django 在这里要做的不是从你的数据库中加载潜在的数十万行,只是设置is_active为 False,然后单独保存每一行,而是UPDATE直接通过数据库引擎发出命令:UPDATE users SET is_active=False WHERE date_joined < 30_DAYS_AGO. 这是 Django 不会post_save在更新时触发的唯一原因:因为它首先没有从数据库中加载任何内容。

为了触发信号,它需要从数据库中加载所有这些对象,发出UPDATE users SET is_active=False WHERE id=X数千次数据库查询,每行一次,然后发送信号。这会扼杀性能。

如果你真的想使用信号,你需要从数据库中加载对象,遍历它们并一次保存一个。不幸的是,没有办法解决这个问题。

于 2017-10-24T18:16:52.447 回答
-3

每当创建或更新 Django 模型对象时,都会调用 save() 方法。

例如:创建新的用户配置文件,更新现有的用户配置文件。

对于这两种情况,我们可以使用 Django 信号发送邮件来通知用户。

为此,我们使用 Django 内置的信号 post_save。

每当在 Django 模型实例上调用 .save() 时,都会调度 post_signal。

我们可以在models.py中使用下面的代码:

from django.db.models import signals
from django.dispatch import receiver
@receiver(signals.post_save, sender=Customer)
def on_create_or_updated_obj(sender, instance, **kwargs):
   if kwargs['created']:
      print 'obj created'
      #send user created email to user
   else:
      print 'obj updated'
      #logic for sending user updated email to user
于 2018-07-26T10:40:15.993 回答