简体   繁体   中英

I have a OneToOne relationship between two objects of the same class in a Django app. Is it possible to enforce the uniqueness of this relationship?

I have the following in my app:

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

I only want a university to be related to one other university in both directions of that relationship.

For example, in the database, if I select university A as the sister_university of university B, I only want to be allowed to select university B as the sister_university under university A also. However, as it is, that second relationship is not enforced.

For example: Right now, under the Django Admin site, if I first select university A as the sister university of university B, I am still able to select any other university as the sister university of the university A object. I'm not constrained to only selecting university B.

Is it possible to enforce that uniqueness at the database level? Is there a better way of accomplishing what I'm trying to do?

I think that what you need is to make this relationship symmetric .

You can accomplish this by overriding the save() method of the University model:

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

I never did this kind of things, but I think that you can make this process through this way :

Method : unique_together()

You can use Options.unique_together and set your university_A and university_B as a unique pair.

unique_together = ("university_A", "university_B")

In your models.py file, you should have something like this (with maybe some issues, but the idea is there) :

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'),)

You should find precious details there : https://docs.djangoproject.com/en/2.0/ref/models/options/

I never tried this command, but it seems to solve your issue according to your context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM