У меня одно отношение OneToOne между двумя объектами одного и того же класса в приложении Django. Можно ли обеспечить уникальность этих отношений?

В моем приложении есть следующее:

class University(models.Model):
    ...
    sister_university = models.OneToOneField('self', related_name = 
                        'university_sister_university', 
                        blank=True, null=True, 
                        on_delete=models.SET_NULL)

Я хочу, чтобы университет был связан с другим университетом в обоих направлениях этих отношений.

Например, в базе данных, если я выберу университет A в качестве сестринского университета университета B, я хочу, чтобы мне разрешалось выбирать университет B как сестра-университет в университете A. Однако, как бы то ни было, эта вторая связь не применяется.

Например: прямо сейчас, на сайте администратора Django, если я сначала выберу университет A в качестве сестринского университета университета B, я все же могу выбрать любой другой университет в качестве сестринского университета университета A. Im не ограничивается только выбором университета B.

Можно ли обеспечить соблюдение этой уникальности на уровне базы данных? Есть ли лучший способ сделать то, что я пытаюсь сделать?

Ответ 1

Я думаю, что вам нужно сделать это соотношение симметричным.

Вы можете сделать это, переопределив метод save() модели University:

def save(self, *args, **kwargs):
    super(University, self).save()
    if self.sister_university:
        self.sister_university.sister_university = self

Ответ 2

Я никогда этого не делал, но я думаю, что вы можете сделать этот процесс таким образом:

Метод: unique_together()

Вы можете использовать Options.unique_together и установить свой университет_A и университет_B как уникальную пару.

unique_together = ("university_A", "university_B")

В файле models.py вы должны иметь что-то вроде этого (возможно, некоторые проблемы, но идея есть):

class University(models.Model):
    ...
    university = models.ForeignKey('self', on_delete=models.CASCADE)
    sister_university = models.ForeignKey('self', on_delete=models.CASCADE)
    class Meta:
        unique_together     = (('university','sister_university'),)

Вы должны найти там драгоценные детали: https://docs.djangoproject.com/en/2.0/ref/models/options/

Я никогда не пробовал эту команду, но, похоже, она решает вашу проблему в соответствии с вашим контекстом.