Django在update()上触发post_save

时间:2017-10-24 16:50:30

标签: python django django-models django-rest-framework django-simple-history

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

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

2 个答案:

答案 0 :(得分:4)

这样做的问题是.update()不必从数据库加载对象来执行它的操作。在具有100万行的用户表上考虑此示例:

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,每行一次,然后发送信号。哪会扼杀性能。

如果您确实想要使用该信号,则需要从数据库加载对象,迭代它们并一次保存一个。不幸的是,没有办法解决这个问题。

答案 1 :(得分:0)

每当创建或更新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