3

私は、多数の異なるモデルを持つ Django アプリを持っており、そのすべてに共通のデータがたくさんあります。最終的に、この問題は継承と構成のどちらを選択するかという問題に行き着くと思います。私の現在の実装は次のようなものです:

class Thing(models.Model):
    foo = models.FooField()
    bar = models.BarField()
    type = models.CharField()

class A(CommonStuff):
    aFoo = models.FooField()

class B(CommonStuff):
    bFoo = models.FooField()

このモデルではThing、Thing モデルのマネージャーを使用してクエリを実行できます。の type フィールドを使用して、'a' または 'b' のいずれかを含むフィールドThingを調べ、 (ie) を要求することで、子オブジェクト データを取得できます。これは、すべてのオブジェクトのリストを取得するためのアプリでのかなり一般的な操作であるため、私が気に入っている機能です。typething.a.aFooThing

ここにはいくつかの問題があります。まず、typeフィールドは不要に思えます。最初に型を調べずに子データを取得する方法はありますか? 型の値を指定して正しいオブジェクトを返すインスタンス メソッドを使用して、これを回避できるようです。または、型フィールドを本当に取り除きたい場合は、 の逆関係フィールドのそれぞれを反復処理してThing、1 つを探します。それはDoesNotExist例外を発生させません。しかし、これは私にはかなりもろく感じます。新しい 'subthing' を追加した場合、新しいタイプを探すためCに更新する必要があります。これは、モデルを作成して抽象化することでThing修正できます。Thingそうすれば、のすべてのフィールドを取得でき、A使用する必要がなくなりますBThingtype分野。Thingただし、問題は、すべてのオブジェクトに対してクエリを実行できなくなることです。

私が考えている別のモデルは、データをとThingのフィールドに変換することで、これをひっくり返します。AB

class Thing(models.Model):
    foo = models.FooField()
    bar = models.BarField()

class A(models.Model):
    aFoo = models.FooField()
    thing = models.OneToOneField(Thing)

class B(models.Model):
    bFoo = models.FooField()
    thing = models.OneToOneField(Thing)

このバージョンにはいくつかの利点があります。type上のフィールドが取り除かれThing、少なくとも私にとっては見た目も手触りもすっきりし、壊れにくくなっています。Thingただし、ここでの問題は、最初のバージョンでアブストラクトを作成する際の問題と同じです。すべての「サブシング」を一緒にクエリする能力を失います。Aオブジェクトのクエリまたはオブジェクトのクエリを実行できますが、両方を実行することはできませBん。すべての「サブシング」を照会する機能を犠牲にすることなく、このバージョンのモデルを使用できますか? QuerySet1 つの可能性は、両方のモデルを照会し、すべてのオブジェクトのを返すマネージャーを作成することです。それは動作しますか?

4

0 に答える 0