Запуск действия при изменении определенного поля в моделях Django

Мне нужно изменить значение OTP_expire каждый раз, когда поле OTP меняет свое значение


class Account(AbstractBaseUser, PermissionsMixin):
    name = models.CharField(max_length=60, null=True)
    username = models.CharField(max_length=30, unique=True)
    password = models.CharField(blank=True)


    OTP = models.IntegerField(null=True)
    OTP_expire = models.DateTimeField(null=True)

Для этого я подумал о создании триггера, но не смог понять, как определить, изменилось ли поле OTP или изменилось другое поле.

Поскольку оба поля находятся в одной модели, вы можете переопределить метод модели save(). Внимательно прочитайте документацию. В частности, обратите внимание на предостережение о массовом создании или обновлении моделей в обход save(). Так что не стоит, или не тогда, когда это важно.

Накладные расходы на обновление OPT_expire при каждом сохранении модели вряд ли будут значительными, поскольку транзакция DB для выполнения сохранения происходит в любом случае. Но если вычисление значения OTP_expire требует больших усилий, вы можете дополнительно зафиксировать, что значение OTP было изменено, заменив это поле свойством. Вы переименуете поле, выполните миграцию, затем установите свойство и, наконец, разберетесь с любыми наборами запросов, которые фильтруют по переименованному полю, поскольку они не могут фильтровать по свойству.

@property
def OTP(self):
    return self.otp   # the actual renamed DB field
@OTP.setter
def OTP(self, value)
    self.otp = value
    self.otp_changed = True

Теперь в вашем методе сохранения,

    if getattr( self, 'otp_changed', False):
         # yes it has been changed, so reset self.otp
         self.otp = something_complicated()
         # and note the documentation on the save method
         update_fields = {"otp"}.union(update_fields)
Вернуться на верх