是否有一种方法来保存Django对象和更新其他对象没有递归循环?



我有一个Django模型:

class Event(models.Model):
fk = models.ForeignKey(Foreign, null=True, on_delete=models.SET_NULL)
display = display = models.BooleanField(default=True)
...

我想重写save方法以关闭共享fk值的其他事件的显示。然而,我一直在达到无限递归循环,因为如果我重写save方法,然后保存其他对象,它会一直调用该函数。是否有一种方法,只运行保存方法上保存的第一个对象,而不是继续创建递归实例?

你可以.update(…)[Django-doc]aQuerySetof other objects, with:

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(…)和预保存和后保存信号(由.save(…)方法触发)。

您还可以添加约束,以强制每个fk最多有一个Event,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'
)
]

相关内容

  • 没有找到相关文章

最新更新