我有一个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]aQuerySet
of 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'
)
]