Проверка изменения поля в модели и создание экземпляра другой модели
У меня есть две модели
Модель проекта
class Project(models.Model):
name = models.CharField(max_length=200)
workflow = models.ForeignKey("WorkflowType", null=True, blank=True, on_delete=models.SET_NULL)
created_on = models.DateTimeField(auto_now_add=True)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, primary_key=True)
def __str__(self):
return self.name
Модель экземпляра рабочего процесса
class WorkflowInstance(models.Model):
workflow_step = models.ForeignKey('WorkflowStep', null=True, blank=True, on_delete=models.CASCADE)
project = models.ForeignKey('Project', null=True, blank=True, on_delete=models.SET_NULL)
Я хочу проверить, добавлено ли или изменено значение поля рабочего процесса в модели "Проект" для конкретного проекта.
Я подхожу к проблеме следующим образом:
Проверяет, отличаются ли предыдущее и новое значение поля "рабочий процесс" в проекте. Если да (изменяет), то создайте новый экземпляр проекта.
@receiver(pre_save, sender=Project)
def projectToBeUpdated(sender, instance, **kwargs):
if instance.id is None:
pass
else:
previous = Project.objects.get(id=instance.id)
if previous.workflow != instance.workflow:
print("workflow value modified. Please create a WorkflowInstance")
Проблема: Сравнение предыдущего и нового значения поля "workflow" происходит в сигнале "pre_save". Но мое создание нового экземпляра для workflowInstance должно быть создано в сигнале "post_save". Как я могу это сделать?
Кроме того, в идеале я хотел бы сохранить предыдущее значение поля workflow в "pre_save" и получить новое значение поля в "post_save". Причина в том, что метод save() может не сработать по любой причине, в то время как я сравниваю предыдущее и новое значение в методе "pre_save". Внесение изменений в базу данных без подтверждения успешного выполнения метода save() было бы неправильным подходом, на мой взгляд.
Вы можете переопределить сам метод сохранения модели и использовать следующую логику кода, дополнительно, если вы хотите определить, какие поля были изменены, вы можете использовать пакет dirtyfields.
def save(self, *args, **kwargs):
if not self._state.adding:
changed_attr = self.get_dirty_fields()
else:
is_new = True
super().save(*args, **kwargs)```