9

Djangoで抽象クラスベースのオブジェクトを照会する方法と同様の問題がありました か? スレッドは、multi_table_inheritance の使用を提案しています。個人的には、 content_type を使用する方が概念的に快適だと思います (少なくとも私にとっては、より論理に近いと感じます)。

前のリンクの例を使用して、StelarType を次のように追加します。

class StellarType(models.Model):
    """
    Use ContentType so we have a single access to all types
    """
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

次に、これを抽象基本モデルに追加します

class StellarObject(BaseModel):
    title = models.CharField(max_length=255)
    description = models.TextField()
    slug = models.SlugField(blank=True, null=True)
    stellartype = generic.GenericForeignKey(StellarType)
    class Meta:
        abstract = True

StellarObject と StellarType の間で同期するには、post_save 信号を接続して、Planet または Star が作成されるたびに StellarType インスタンスを作成します。このようにして、StellarType を介して StellarObjects をクエリできます。それで、multi_table_inheritance の使用に対してこのアプローチを使用することの長所と短所は何ですか? どちらもデータベースに追加のテーブルを作成すると思います。しかし、データベースのパフォーマンスはどうですか? 使いやすさ/柔軟性はどうですか?ご意見をお寄せいただきありがとうございます。

4

2 に答える 2

6

私にとって、ContentType は、基本的に同じ「タイプ」ではない多くのモデルの 1 つにオブジェクトを関連付けたい場合に使用する方法です。たとえば、ソーシャル ネットワークでユーザー、ページ、および画像にコメントをキー設定できるようにしたいが、これら 3 つのモデルで共有される合理的なスーパータイプが存在しない場合などです。確かに「コメント可能な」スーパータイプを作成できますが、私には、これら 3 つのものが派生する基本的なタイプというよりは、ミックスインのように感じられます。ContentType が登場する前は、この種のリレーションのスーパータイプを発明するしかありませんでした。これは、同じアプリケーションで複数回実行する必要がある場合、非常にすぐに醜くなる可能性があります (イベント、アラート、メッセージなど、それぞれが異なるモデルのセットに適用できます)。

複数テーブルの継承は、ベース モデルに属性をアタッチして、そこから拡張されたすべての具体的なモデルで属性を共有し、ポリモーフィックな動作を取得できるようにする場合に最も有効です。Commentable は、実際にはこの型に適合しません。なぜなら、その動作はすべて Comment モデルに置くことができ、Commentable オブジェクトにはあまり当てはまらないからです。しかし、同じ振る舞いを共有し、集約可能であるべき異なるクラスのユーザーがいる場合、それはより理にかなっています。

私にとってのマルチテーブル継承の主な利点は、Python 側で利用できる暗黙的なリレーションシップと継承を備えた、よりクリーンなデータ モデルです (ここここで見られるように、ポリモーフィズムはまだ少し厄介です)。ContentType の主な長所は、より一般的であり、モデルから補助機能を除外することですが、その代償として、元のスキーマ (これらの関係を定義するためのモデルの多くの「メタ」フィールド) が少し少なくなります。そして、あなたの例では、私post_saveにも不必要に面倒/魔法のように見える に依存する必要があります。

于 2012-10-19T08:40:49.833 に答える
0

古いスレッドを復活させてすみません。私はそれがルックアップ方向に要約すると思います。特定の FK (マルチテーブル継承) のすべてのサブクラスを検索するか、参照されるクラスをコンテンツ タイプとして定義し、テーブル参照と ID (コンテンツ タイプ) に基づいて検索するかにかかわらず、パフォーマンスに大きな違いはありません - ヒント: どちらも最悪です。アプリを簡単に拡張できるようにしたい場合、つまり他のユーザーが新しいコンテンツ タイプを追加して参照できるようにしたい場合、コンテンツ タイプは良い選択だと思います。マルチテーブルは、追加のテーブルで定義された追加の列が時々必要になる場合に適しています。場合によっては、すべてのサブタイプをマージして、ほとんどの場合、いくつかのフィールドが空のままになっているサブタイプを 1 つだけ作成することも良い考えです。

于 2015-12-24T00:32:51.777 に答える