Django模型与多个模型的关系

Posted

技术标签:

【中文标题】Django模型与多个模型的关系【英文标题】:Django model relationship to multiple models 【发布时间】:2014-01-22 11:34:26 【问题描述】:

假设有一个抽象模型 CarOwner:而 Person 或 Business 可以是 CarOwner。此外,具有特定 VIN 的汽车可以属于(相关)个人或企业,但不能同时属于(相互排斥的情况)。在以下代码的最后,我提出了两种可能性(参见代码中的 cmets “#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)

【问题讨论】:

【参考方案1】:

由于CarOwner 是抽象的,你不能做#1。您可以将CarOwner 具体化(数据库表继承),然后这会起作用,但是表继承会带来一系列复杂性。您可以执行 #2 或使用通用外键:

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

【讨论】:

【参考方案2】:

就像 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")

但是,对于查询,您必须使用 personbusiness

【讨论】:

谢谢。那么,实际上允许在同一个模型中使用两个 ForeignKey 吗?从我过去对 Django 文档网站的探索中,我之前了解到它只允许用于某些多对多关系的情况。 当然可以,我不确定 Django 文档的哪一部分可以提出其他建议。

以上是关于Django模型与多个模型的关系的主要内容,如果未能解决你的问题,请参考以下文章

Django:无法创建与一个普通模型具有一对一关系的多个模型对象

跨多个模型定义关系 - Django

使 ModelForm 与 Django 中的中间模型的多对多关系工作的步骤是啥?

多个 django 会话表

Django进阶Model篇002 - 模型类的定义

Django 模型层之多表操作