あなたは継承について考えすぎているのではないかと思います。継承は、実際にモデルを合成するための推奨される方法です。以下は、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すること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__の属性を手動で入力したかのように、基本モデルから属性をコピーします。そのようなものの外部キーにはなりません。継承された属性はすべてモデルの一部になり、同じテーブルに配置されます。
うまくいけば、これはすべて何らかの意味があります。そうでない場合は、覚えておく必要があるのは、Metaclass withを使用することだけabstract = Trueです。
編集
コメントで示唆されているように、複数の基本クラスから継承することもできます。したがってPhoneModelBase、DimensionsModelBase、 、およびこれらの両方 (またはそれ以上) から継承することができ、すべての基本クラスのすべての属性がモデルに存在します。