Django模型与多个模型的关系

Django模型与多个模型的关系,django,django-models,foreign-key-relationship,many-to-one,django-orm,Django,Django Models,Foreign Key Relationship,Many To One,Django Orm,假设有一个抽象的车主模型:而一个人或一个企业可以是车主。此外,具有特定VIN的汽车可以属于(关联)个人或企业,但不能同时属于(关联)两者(互斥情况)。在下面代码的最后,我介绍了两种可能性(请参见代码中的注释“#1.我应该有这个吗?””和“#2…或者我应该有这个吗?”)。在第一种可能性中,将多对一关系建立为抽象模型,我不确定这是否正确。在第二种情况下,建立了两种关系,我不确定这是否正确,尤其是不清楚如何使它们相互排斥。那么,哪一个是正确的,如果两者都不对,请尽可能提供正确的答案。谢谢 class

假设有一个抽象的车主模型:而一个人或一个企业可以是车主。此外,具有特定VIN的汽车可以属于(关联)个人或企业,但不能同时属于(关联)两者(互斥情况)。在下面代码的最后,我介绍了两种可能性(请参见代码中的注释“#1.我应该有这个吗?””和“#2…或者我应该有这个吗?”)。在第一种可能性中,将多对一关系建立为抽象模型,我不确定这是否正确。在第二种情况下,建立了两种关系,我不确定这是否正确,尤其是不清楚如何使它们相互排斥。那么,哪一个是正确的,如果两者都不对,请尽可能提供正确的答案。谢谢

class CarOwner(models.Model):
    location = models.CharField(max_length=50, blank=True)

    class Meta:
        abstract = True

class Person(CarOwner):
    name = models.CharField(max_length=50, blank=True)

class Business(CarOwner):
    business_id = models.CharField(max_length=50, blank=True)

class Car(models.Model):
    vin = models.CharField(max_length=50, blank=True)

    # 1. SHOULD I HAVE THIS??? (CarOwner is abstract)
    carowner = models.ForeignKey(CarOwner, blank=True, null=True)

    # 2. ...OR SHOULD I HAVE THIS???
    person = models.ForeignKey(Person, blank=True, null=True)
    business = models.ForeignKey(Business, blank=True, null=True)

因为车主是抽象的,所以你不能这样做。您可以将
CarOwner
具体化(db table inheritation),然后这就可以了,但是table inheritation带来了它自己的一系列复杂问题。您可以执行#2或使用通用外键:

carowner_content_type = models.ForeignKey(ContentType)
carowner_object_id = models.PositiveIntegerField()
carowner = generic.GenericForeignKey('carowner_content_type', 'carowner_object_id')

正如jproffitt提到的,泛型关系可能是一个很好的解决方案。或者,您可以使用#2,通过创建属性并向其添加一些简单的逻辑,使其更加方便:

class Car(models.Model):
    vin = models.CharField(max_length=50, blank=True)
    person = models.ForeignKey(Person, blank=True, null=True)
    business = models.ForeignKey(Business, blank=True, null=True)

    @property
    def carowner(self):
        return self.person or self.business

    @carowner.setter
    def carowner(self, obj):
        if type(obj) == Person:
            self.person = obj
            self.business = None
        elif type(obj) == Business:
            self.business = obj
            self.person = None
        else:
            raise ValueError("obj parameter must be an object of Business or Person class")

但是,对于查询,您必须使用person或business

谢谢。那么,在同一个模型中使用两个外键实际上是允许的?从我过去对Django doc网站的探索中,我以前了解到,它只适用于多对多关系的某些情况。当然,我不确定Django文档的哪一部分可能暗示其他内容。