Запуск действия при изменении определенного поля в моделях 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)