简体   繁体   English

Django在update()上触发post_save

[英]Django trigger post_save on update()

So I am using django-simple-history module that tracks changes in Model instances. 所以我正在使用django-simple-history模块,该模块跟踪Model实例中的更改。 However, it uses post_save signal to do so. 但是,它使用post_save信号来这样做。 In my project, I also need it to trigger on update(). 在我的项目中,我还需要它在update()上触发。

My question is: How to overwrite the update() method to trigger post_save signals? 我的问题是:如何覆盖update()方法以触发post_save信号?

The problem you'll have by doing this is that .update() doesn't have to load the objects from the database in order to do its thing. 这样做的问题是, .update()不必为了执行其工作而从数据库中加载对象。 Consider this example on a users table with 1 million rows: 考虑具有100万行的用户表上的以下示例:

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

What django will do here is not load potentially hundreds of thousands of rows from your database, just to set is_active to False, then save each row individually, but instead issue an UPDATE command via the database engine directly: UPDATE users SET is_active=False WHERE date_joined < 30_DAYS_AGO . django不会在数据库中加载可能成千上万的行,只是将is_active为False,然后分别保存每一行,而是直接通过数据库引擎发出UPDATE命令: UPDATE users SET is_active=False WHERE date_joined < 30_DAYS_AGO This is the sole reason Django does not trigger post_save on update: because it hasn't loaded anything from the database in the first place. 这是Django在更新时不触发post_save的唯一原因:因为它首先没有从数据库中加载任何东西。

In order for it to trigger the signal, it would need to load all those objects from the database, issue a database query UPDATE users SET is_active=False WHERE id=X thousands of times, once for each row, then send the signal. 为了使其触发信号,它将需要从数据库中加载所有这些对象,发出数据库查询UPDATE users SET is_active=False WHERE id=X数千次,每行一次,然后发送信号。 Which would kill performance. 这会降低性能。

If you really want to use the signal, you will need to load the objects from the database, iterate over them and save them one at a time. 如果您确实想使用信号,则需要从数据库中加载对象,对其进行迭代并一次保存一个。 There's no way around this unfortunately. 不幸的是,这没有办法。

save() method is called whenever Django model object is created or updated. 每当创建或更新Django模型对象时,都会调用save()方法。

ex: Creating a new user profile, Updating existing user profile. 例如:创建一个新的用户配置文件,更新现有的用户配置文件。

We can use Django signals to send mails to notify the user for these two scenarios. 在这两种情况下,我们可以使用Django信号发送邮件以通知用户。

For this we use Django built in signal post_save. 为此,我们使用内置于信号post_save的Django。

post_signal will be dispatched whenever .save() is called on Django model instance. 每当在Django模型实例上调用.save()时,都会调度post_signal。

we can use below code in models.py: 我们可以在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

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

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