识别django post_save信号中已更改的字段

时间:2022-09-11 18:26:14

I'm using django's post_save signal to execute some statements after saving the model.

我在保存模型后使用django的post_save信号执行一些语句。

class Mode(models.Model):
    name = models.CharField(max_length=5)
    mode = models.BooleanField()


from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Mode)
def post_save(sender, instance, created, **kwargs):
        # do some stuff
        pass

Now I want to execute a statement based on whether the value of the mode field has changed or not.

现在我想根据模式字段的值是否已更改来执行语句。

@receiver(post_save, sender=Mode)
def post_save(sender, instance, created, **kwargs):
        # if value of `mode` has changed:
        #  then do this
        # else:
        #  do that
        pass

I looked at a few SOF threads and a blog but couldn't find a solution to this. All of them were trying to use the pre_save method or form which are not my use case. https://docs.djangoproject.com/es/1.9/ref/signals/#post-save in the django docs doesn't mention a direct way to do this.

我查看了一些SOF主题和博客,但找不到解决方案。他们都试图使用pre_save方法或形式,这不是我的用例。 django docs中的https://docs.djangoproject.com/es/1.9/ref/signals/#post-save没有提到直接的方法来做到这一点。

An answer in the link below looks promising but I don't know how to use it. I'm not sure if the latest django version supports it or not, because I used ipdb to debug this and found that the instance variable has no attribute has_changed as mentioned in the below answer.

下面的链接中的答案看起来很有希望,但我不知道如何使用它。我不确定最新的django版本是否支持它,因为我使用ipdb来调试它,并发现实例变量没有属性has_changed,如下面的答案所述。

Django: When saving, how can you check if a field has changed?

Django:保存时,如何检查字段是否已更改?

2 个解决方案

#1


13  

Set it up on the __init__ of your model so you'll have access to it.

将其设置在模型的__init__上,以便您可以访问它。

def __init__(self, *args, **kwargs):
    super(YourModel, self).__init__(*args, **kwargs)
    self.__original_mode = self.mode

Now you can perform something like:

现在你可以执行以下操作:

if instance.mode != instance.__original_mode:
    # do something useful

#2


20  

Ussually it's better to override the save method than using signals.

通常,覆盖保存方法比使用信号更好。

From Two scoops of django: "Use signals as a last resort."

来自两勺django:“使用信号作为最后的手段。”

I agree with @scoopseven answer about caching the original value on the init, but overriding the save method if it's possible.

我同意@scoopseven关于在init上缓存原始值的答案,但如果可能则覆盖save方法。

class Mode(models.Model):
    name = models.CharField(max_length=5)
    mode = models.BooleanField()
    __original_mode = None

    def __init__(self, *args, **kwargs):
        super(Mode, self).__init__(*args, **kwargs)
        self.__original_mode = self.mode

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        if self.mode != self.__original_mode:
            #  then do this
        else:
            #  do that

        super(Mode, self).save(force_insert, force_update, *args, **kwargs)
        self.__original_mode = self.mode

#1


13  

Set it up on the __init__ of your model so you'll have access to it.

将其设置在模型的__init__上,以便您可以访问它。

def __init__(self, *args, **kwargs):
    super(YourModel, self).__init__(*args, **kwargs)
    self.__original_mode = self.mode

Now you can perform something like:

现在你可以执行以下操作:

if instance.mode != instance.__original_mode:
    # do something useful

#2


20  

Ussually it's better to override the save method than using signals.

通常,覆盖保存方法比使用信号更好。

From Two scoops of django: "Use signals as a last resort."

来自两勺django:“使用信号作为最后的手段。”

I agree with @scoopseven answer about caching the original value on the init, but overriding the save method if it's possible.

我同意@scoopseven关于在init上缓存原始值的答案,但如果可能则覆盖save方法。

class Mode(models.Model):
    name = models.CharField(max_length=5)
    mode = models.BooleanField()
    __original_mode = None

    def __init__(self, *args, **kwargs):
        super(Mode, self).__init__(*args, **kwargs)
        self.__original_mode = self.mode

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        if self.mode != self.__original_mode:
            #  then do this
        else:
            #  do that

        super(Mode, self).save(force_insert, force_update, *args, **kwargs)
        self.__original_mode = self.mode