Есть ли способ сохранить объект Django и обновить другие объекты без рекурсивного цикла?
У меня есть модель Django:
class Event(models.Model):
fk = models.ForeignKey(Foreign, null=True, on_delete=models.SET_NULL)
display = display = models.BooleanField(default=True)
...
Я хотел бы переопределить метод сохранения, чтобы отключить отображение для других событий, имеющих общее значение fk. Однако я продолжаю достигать бесконечных циклов рекурсии, потому что если я переопределяю метод сохранения, а затем сохраняю другие объекты, он продолжает вызывать функцию. Есть ли способ запустить метод сохранения только для первого сохраняемого объекта и не создавать рекурсивные экземпляры?
Вы можете работать .update(…)
[Django-doc] с QuerySet
другими объектами, с:
from django.db.models import Q
class Event(models.Model):
fk = models.ForeignKey(Foreign, null=True, on_delete=models.SET_NULL)
display = models.BooleanField(default=True)
# …
def save(self, *args, **kwargs):
if self.fk_id is not None and self.display:
Event.objects.filter(
~Q(pk=self.pk), fk_id=self.fk_id
).update(display=False)
return super().save(*args, **kwargs)
Но это также сразу показывает, что есть способы обойти .save(…)
метод [Django-doc] на модели, поэтому простого переопределения .save(…)
будет не достаточно, поскольку существуют методы ORM, которые обходят .save(…)
и сигналы pre-save и post-save (которые вызываются методом .save(…)
).
Вы также можете добавить ограничение для обеспечения того, что существует не более одного Event
для каждого fk
, который имеет display=True
:
from django.db.models import Q
class Event(models.Model):
fk = models.ForeignKey(Foreign, null=True, on_delete=models.SET_NULL)
display = models.BooleanField(default=True)
# …
class Meta:
constraints = [
models.UniqueConstraint(
fields=('fk',),
condition=Q(display=True),
name='only_one_display_per_fk'
)
]