3

寸法( w​​idthheight ) や電話番号( prefixnumberextension )などの複合プロパティを持つ複数のクラスをモデル化する必要があるとします。

Java (JPA 2 を使用) では、Dimensionsクラスを作成し、それに注釈を付け@Embeddableます。これにより、Dimension のフィールド (高さなど) が、 Dimensions型のプロパティを宣言するすべてのクラスに埋め込まれます。

コードの重複を避けながら、これらを Django でどのようにモデル化しますか? 個別のディメンションモデルを作成し、それをForeignKeyフィールドで参照することは意味がありません。また、クラスには、モデルの継承を正当化するのに十分な共通点がありません。

4

1 に答える 1

5

あなたは継承について考えすぎているのではないかと思います。継承は、実際にモデルを合成するための推奨される方法です。以下は、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) をそれに渡します。phoneMetaおよび定義したその他のフィールドが含まれます
  • 属性を認識し、Metaその属性の分析を開始します。これらの属性の値に応じて、Django はモデルの動作を変更します。
  • 属性abstractを確認し、作成しようとしているクラスのロジックを変更します-PhoneModelBaseデータベースに保存しないことにより

したがって、 はPhoneModelBase、その定義が通常のモデルに非常に似ているように見えますが、通常のモデルではありません。これは、他のモデルで複合として使用されることを意図した単なる抽象クラスです。

他のモデルが から継承する場合、これらのモデルはPhoneModelBase、それら__metaclass__の属性を手動で入力したかのように、基本モデルから属性をコピーします。そのようなものの外部キーにはなりません。継承された属性はすべてモデルの一部になり、同じテーブルに配置されます。

うまくいけば、これはすべて何らかの意味があります。そうでない場合は、覚えておく必要があるのは、Metaclass withを使用することだけabstract = Trueです。

編集

コメントで示唆されているように、複数の基本クラスから継承することもできます。したがってPhoneModelBaseDimensionsModelBase、 、およびこれらの両方 (またはそれ以上) から継承することができ、すべての基本クラスのすべての属性がモデルに存在します。

于 2012-09-19T12:20:50.157 に答える