我认为你可能过度思考继承。继承是并且实际上是组合模型的推荐方法。以下是如何在 Django 中正确使用模型继承的示例:
class PhoneModelBase(model.Model):
phone = models.CharField(max_length=16)
...
class Meta:
abstract = True
class PhoneModel(PhoneModelBase):
# phone is here without typing it
# the only restriction is that you cannot redefine phone here
# its a Django restriction, not Python restriction
# phone = models.CharField(max_length=12) # <= This will raise exception
pass
所以它的作用是创建一个模型PhoneModelBase
,但这里的关键是它使用class Meta
with abstract=True
。
这里有更多关于正在发生的事情的幕后故事以及对一些 Python 概念的一些解释。我假设您不知道它们,因为您在问题中提到了 Java。这些 Python 概念实际上是相当混乱的概念,所以我的解释可能并不完整,甚至令人困惑,所以如果你不遵循,请不要介意。您所需要知道的就是使用abstact = True
. 这是官方文档:https ://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes 。
Meta
里面的属性PhoneModelBase
就是这样,一个属性。它与类中的任何其他属性相同,除了它是一个类实例(请记住,在 Python 中,类和函数是一阶成员)。此外,Python 有一个叫做的东西__metaclass__
,你可以将它添加到你的类中。__metaclass__
定义了如何构建类的实例的方式。更多关于这里。Django 使用这些来创建模型类实例。
所以要创建这个PhoneModelBase
类,下面是一个粗略的大纲:
- 当创建类的实例
PhoneModelBase
(类本身,而不是类的实例 - PhoneModelBase()
)时,__metaclass__
由于model.Model
继承而产生的 接管创建过程
- 在 中
__metaclass__
,Python 调用创建实际类实例的函数并将您尝试创建的类中的所有字段 - PhoneModelBase 传递给它。这将包括phone
,Meta
以及您定义的任何其他字段
- 它看到
Meta
属性,然后开始分析其属性。根据这些属性的值,Django 会改变模型的行为
- 它看到
abstract
属性,然后改变它试图创建的类的逻辑——PhoneModelBase
不将它存储在数据库中
因此PhoneModelBase
,即使它的定义看起来与常规模型非常相似,它也不是常规模型。它只是一个抽象类,旨在在其他模型中用作复合材料。
当其他模型继承自 时PhoneModelBase
,它们__metaclass__
将从基本模型中复制属性,就像您手动键入这些属性一样。它不会是这样的外键。所有继承的属性都将成为模型的一部分,并将在同一个表中。
希望所有这些都有意义。如果没有,您只需要记住使用Meta
class with即可abstract = True
。
编辑
正如评论中所建议的,您还可以从多个基类继承。因此,您可以拥有PhoneModelBase
, DimensionsModelBase
,然后您可以从这两个(或更多)继承,并且所有基类的所有属性都将出现在您的模型中。