我有以下对象:
from django.db import models
class Page(models.Model):
prev_sibling = models.OneToOneField('self', related_name='next_sibling',
null=True, blank=True)
我有几个这些对象的实例。我们说A, B, C
和D
。我已经分配了兄弟关系,A
B
为prev_sibling
,C
D
为prev_sibling
。
现在想象一下我想要交换B
和D
。我只需重新分配属性,如下所示:
A.prev_sibling = D
A.save()
C.prev_sibling = B
C.save()
但是,由于我不再满足IntegrityError
在第一个OneToOneField
之后隐含的唯一性约束,因此失败了save()
。
我尝试在事务中包装代码,希望这可以确保保存以原子方式发生,从而防止临时约束违规,如下所示:
from django.db import transaction
with transaction.atomic():
A.prev_sibling = D
A.save()
C.prev_sibling = B
C.save()
但那没用。解决这个问题的正确方法是什么?
编辑:对于记录:我也尝试过顺序分配然后保存(如下所示),但正如人们所预料的那样,行为也没有区别。
with transaction.atomic():
A.prev_sibling = D
C.prev_sibling = B
A.save()
C.save()
答案 0 :(得分:0)
您违反了数据库限制。在保存之前,您需要清除另一个,以便数据库始终处于有效的状态。州。当然,在将它们设置为None之后,它在技术上并不是理想的状态,但它对于数据库约束来说是有效的。
这应该对你有用,但如果在将它们保存为None
并设置属性之间发生了不好的事情,你显然有可能失去关系。
Page.objects.filter(id__in=[A.id, C.id]).update(prev_sibling=None)
A.prev_sibling = D
A.save()
C.prev_sibling = B
C.save()