我在 Django 应用程序中同一类的两个对象之间存在 OneToOne 关系。是不是可以强制执行这种关系的唯一性?

Posted

技术标签:

【中文标题】我在 Django 应用程序中同一类的两个对象之间存在 OneToOne 关系。是不是可以强制执行这种关系的唯一性?【英文标题】: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?我在 Django 应用程序中同一类的两个对象之间存在 OneToOne 关系。是否可以强制执行这种关系的唯一性? 【发布时间】:2018-10-25 14:41:03 【问题描述】:

我的应用中有以下内容:

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 Admin 站点下,如果我首先选择大学 A 作为大学 B 的姊妹大学,我仍然可以选择任何其他大学作为大学 A 对象的姊妹大学。我不仅限于选择大学 B。

是否可以在数据库级别强制执行该唯一性?有没有更好的方法来完成我想做的事情?

【问题讨论】:

这个我自己没试过,所以没有详细的答案,不过你可以看看this solution。 我可以确认您可以这样做;但约束没有被强制执行;即使您设置unique_together 也不会。我想这首先是一个 SQL 问题;在成为 django 问题之前。 softwareengineering.stackexchange.com/questions/325284/… 【参考方案1】:

我认为您需要使这种关系对称

您可以通过覆盖 University 模型的 save() 方法来完成此操作:

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

【讨论】:

@BearBrown,这是否意味着有时您希望UniversityAUniversityB 用作sister_universityUniversityBnull 用作sister_university @BearBrown,哦,好吧..据我了解,他需要对称性才能始终发生。你怎么看? 不幸的是,它在 admin 中对我不起作用,鉴于我必须保存这两个实例,请问有什么建议吗?【参考方案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/

我从未尝试过此命令,但它似乎根据您的上下文解决了您的问题。

【讨论】:

三所大学,a, b, c 如果a 是姐姐b 那么c 不能是姐姐a,我不认为unique_together 有帮助。 @BearBrown 是的,但是如果我很好地理解了这个问题,那么只有大学 A 和 B 不是吗?他只是想结对大学? 没有唯一的两侧。其他方式我没有创造赏金。 哼,我觉得unique_togetherthrough model带信号是解决他问题的唯一办法。

以上是关于我在 Django 应用程序中同一类的两个对象之间存在 OneToOne 关系。是不是可以强制执行这种关系的唯一性?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用基于类的视图在同一模板中使用两个不同的 Django 表单

eclipse 同一个包下两个类之间 如何调用?

Java:观察同一类的许多对象

django - 模型之间的关系

如何在 django 中同时获取两个模型

同一对象中的 QTcpSocket 到 QTcpSocket