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