У меня есть следующий объект:подкачка значения в OneToOneField: IntegrityError
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()
Но это не сработало. Каков правильный способ решить эту проблему?
EDIT: Для записи: Я также попытался последовательно назначать, а затем сохранять (как указано ниже), но, как можно было бы ожидать, поведение ничем не отличается.
with transaction.atomic():
A.prev_sibling = D
C.prev_sibling = B
A.save()
C.save()
Вы пробовали с [совершить параметров в 'save' метод] (https://docs.djangoproject.com/en/stable/topics/forms/modelforms/#the-save-method)? – Gocht
Я не совсем понимаю, как это уместно. Метод 'save', который поставляется с формами, похоже, имеет этот параметр, а не' save() 'на моделях, и это, похоже, не затрагивает эту проблему. – Joost
Извините, транзакции имеют функцию [commit] (https://docs.djangoproject.com/en/stable/topics/db/transactions/#django.db.transaction.commit). – Gocht