私は、多数の異なるモデルを持つ 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) を要求することで、子オブジェクト データを取得できます。これは、すべてのオブジェクトのリストを取得するためのアプリでのかなり一般的な操作であるため、私が気に入っている機能です。type
thing.a.aFoo
Thing
ここにはいくつかの問題があります。まず、type
フィールドは不要に思えます。最初に型を調べずに子データを取得する方法はありますか? 型の値を指定して正しいオブジェクトを返すインスタンス メソッドを使用して、これを回避できるようです。または、型フィールドを本当に取り除きたい場合は、 の逆関係フィールドのそれぞれを反復処理してThing
、1 つを探します。それはDoesNotExist
例外を発生させません。しかし、これは私にはかなりもろく感じます。新しい 'subthing' を追加した場合、新しいタイプを探すためC
に更新する必要があります。これは、モデルを作成して抽象化することでThing
修正できます。Thing
そうすれば、のすべてのフィールドを取得でき、A
使用する必要がなくなりますB
Thing
type
分野。Thing
ただし、問題は、すべてのオブジェクトに対してクエリを実行できなくなることです。
私が考えている別のモデルは、データをとThing
のフィールドに変換することで、これをひっくり返します。A
B
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
ん。すべての「サブシング」を照会する機能を犠牲にすることなく、このバージョンのモデルを使用できますか? QuerySet
1 つの可能性は、両方のモデルを照会し、すべてのオブジェクトのを返すマネージャーを作成することです。それは動作しますか?