如何使Django OneToOneField在类之间互斥

时间:2019-07-01 20:56:35

标签: python django django-models

我有:myARecord = models.OneToOneField(ClassA,...),由两个不同的类B和C使用。

在Django管理员中,它使我可以创建引用相同A记录的B记录和C记录。 B或C的两个实例无法引用相同的A记录。

我如何对B类和C类的所有记录实施这种互斥性?

1 个答案:

答案 0 :(得分:1)

OneToOneField基本上是设置了unique=True的外键,这意味着:

  1. 因为它是一个外键,所以它引用的实例也可以由其他具有该实例作为外键值的实例引用
  2. unique=True意味着该值在整个表中应该是唯一的,这意味着模型ClassB的两个实例不能具有指向ClassA的指向相同的外键值,而一个实例ClassB中的ClassA模型可以具有与ClassC的一个实例相同的外键值,依此类推

话虽如此,以这种方式强制执行严格的一对一关系只能在两个表之间进行,而不能在三个表之间进行。在这种情况下,您可以创建一些自定义验证,例如:

class ClassB(models.Model):
    a_reference = models.OneToOneField(ClassA)

    def save(self, *args, **kwargs):
        class_c_instances_with_same_value = ClassC.objects.filter(a_reference=self.a_reference)
        if class_c_instances_with_same_value:
            raise ValidationError
        super(ClassB, self).save(*args, **kwargs)

,但是您必须在所有课程中都这样做。也许创建一个mixin类,并在要实施该类的所有类中使用该类。

注意:正如Kevin Christopher Henry在评论中指出的那样,您可能希望将验证保留在clean() method中。