В Django 2.2.1 у меня есть две модели, связанные через OneToOneField:
class Woman(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Man(models.Model):
name = models.CharField(max_length=100)
wife = models.OneToOneField(
Woman,
related_name = 'husband',
null=True,
blank=True,
on_delete=models.SET_NULL
)
def __str__(self):
return self.name
(гетеронормативно для простоты.) Но, как мы все знаем, браки терпят неудачу.Тем не менее, я ужасно изменяю отношения:
>>> john = Man.objects.create(name='John')
>>> alice = Woman.objects.create(name='Alice')
>>> susan = Woman.objects.create(name='Susan')
>>> john.wife = alice
>>> alice.husband
<Man: John>
# After the divorce...
>>> john.wife = susan
>>> susan.husband
<Man: John>
>>> alice.husband
<Man: John>
>>> susan.save()
Traceback (most recent call last):
...
django.db.utils.IntegrityError: UNIQUE constraint failed: appname_woman.husband_id
Хорошо, это имеет смысл: два объекта Woman не могут иметь одного мужа (по крайней мере, в соответствии с действующим законодательством США).Нет проблем;Что делать, если я удаляю оригинальную жену из отношений?
>>> alice.husband = None
>>> alice.save()
>>> alice.husband # None
>>> susan.husband
<Man: John>
# Oh good, no errors. And John is now married to Susan... right? Wrong.
>>> john.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/project/venv/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 415, in __get__
self.related.get_accessor_name()
appname.models.Man.wife.RelatedObjectDoesNotExist: Man has no wife.
Похоже, что единственный способ сделать это - это развестись с Джоном до того, как он вступит в повторный брак:
# Starting with a clean database
>>> john = Man.objects.create(name='John')
>>> alice = Woman.objects.create(name='Alice')
>>> susan = Woman.objects.create(name='Susan')
>>> john.wife = alice
>>> alice.husband
<Man: John>
# The marriage was brief...
>>> john.wife = None
>>> john.save()
>>> john.wife = susan
>>> john.save()
>>> susan.save()
>>> alice.save()
# Everybody's happy, we hope.
Какой беспорядок!Теперь вот мой вопрос: как я могу написать код, чтобы гарантировать, что каждый раз, когда объекты Man присваиваются новой Man.wife, предыдущая Man.wife удаляется и проверка проходит успешно?