Django有条件地基于两个抽象类建立模型



我有更多的概念性问题,但具有实际意义。
在Django 4.1中。x应用程序,我有一个owner类,可以是personorganization,但从来没有在一起。
这两个类不需要在数据库中注册,只有owner必须注册:

from django.db import models
class Person(models.Model):
first_name = models.CharField(
max_length=256,
verbose_name=_("First name"),
null=False,
)
# other person attributes, e.g.:
surname = models.CharField(
max_length=256,
verbose_name=_("Surname"),
null=False,
)
street = models.CharField(
max_length=256,
verbose_name=_("Street"),
null=False,
)
country = models.CharField(
max_length=256,
verbose_name=_("Country"),
null=False,
)
class Meta:
abstract = True

def __str__(self):
return self.first_name
class Organization(models.Model):
full_name = models.CharField(
max_length=256,
verbose_name=_("Full name"),
null=False,
)
# other organization attributes, e.g.:
register_identifier = models.CharField(
max_length=64,
verbose_name=_("Register identifier"),
null=False,
)
street = models.CharField(
max_length=256,
verbose_name=_("Street"),
null=False,
)
country = models.CharField(
max_length=256,
verbose_name=_("Country"),
null=False,
)

class Meta:
abstract = True

def __str__(self):
return self.full_name

无论owner实例是什么,它必须有一个name属性:
对于个人,所有者的名称必须是first_name,对于组织,所有者的名称必须是full_name

同样,如果owner对象是Person的实例:我只想公开Person的其他属性。同样,如果ownerOrganization的实例。

我在这里肯定错过了一些概念/也许我没有朝正确的方向看,但是如何基于"条件或参数化继承"类型构建owner模型?

请注意,Person类也用于构建其他对象,例如整个应用程序中的designerpainterOrganization也是如此,它作为不同类型组织的基础。因此他们的abstract = True

编辑

正如SamSparx在下面的评论中建议的那样,我尝试使用吸引人的"代理"。的概念。为此,我需要从PersonOrganization类中删除abstract = True标志,并在Owner类中设置proxy = True。但是,当尝试makemigrations时,它说:

TypeError: Proxy model 'Owner' has more than one non-abstract model base class.
class Owner(Organisation, Person):
class Meta:
proxy = True

这是预期的文档说:基类限制

代理模型必须完全继承一个非抽象模型类。您不能从多个非抽象模型中继承,因为代理模型不提供不同数据库表中的行之间的任何连接。代理模型可以继承任意数量的抽象模型类,只要它们不定义任何模型字段。代理模型也可以继承任意数量的代理模型,这些代理模型共享一个公共的非抽象父类。

来源:https://docs.djangoproject.com/en/4.1/topics/db/models/base-class-restrictions

所以它目前没有真正的帮助。

有几种可能的方法,但它们都有权衡。这在很大程度上取决于所有类都使用同一个表的重要性。根据经验,如果一个非抽象模型需要新的字段,它就需要一个新的表。

抽象类:

这些作为原型是有用的,但你不能把它们组合起来,然后只有一个抽象类"活动"。如果Org和Person都是用来创建Owner的抽象类,那么Owner将拥有这两个类中的所有字段。

任何非抽象类都需要自己的表,例如Owner的子类或其他具有Person抽象的类。

代理类:

这基本上是只使用一个表的选项。使用这个方法,你可以使用同一个表为你的类和它的子类创建单独的子类,每个类都有不同的方法和属性。但是,它们都必须共享相同的字段。如果只是偶尔需要新字段,则可以将它们添加到基类中,而不需要太多的开销,并通过相应的代理类的方法处理或忽略它们。

相关内容

  • 没有找到相关文章

最新更新