32

2つのクラスの共通属性を抽象基本クラスに分解しましたが、これらのクラスのいずれかを参照する必要がある別のモデルがあります。ABCには実際にはデータベーステーブルがないため、ABCを参照することはできません。

次の例は私の問題を説明するはずです:

class Answer(models.Model):
    ovramt = models.ForeignKey("Ovramt")
    question = models.ForeignKey("Question")
    answer = models.CharField(max_length=3, choices=(("yes","yes"),("no","no") ("NA","N/A"))
    likelihood = models.IntegerField(choices=LIKELY_CHOICES)
    consequence = models.IntegerField(choices=CONSEQUENCE_CHOICES)

    class Meta:
        abstract = True

class Answer_A(Answer):
    resident = models.ForeignKey("Resident")
    def __unicode__(self):
        return u"%s - %s - %s" %(self.ovramt.ssa.name, self.resident, self.question)    

class Answer_B(Answer):
    def __unicode__(self):
        return u"%s - %s" %(self.ovramt.ssa.name, self.question)    

class Answer_Risk(models.Model):
    answer = models.ForeignKey("Answer")
    risk = models.CharField(max_length=200)

    def __unicode__(self):
        return self.risk

Answer_AとAnswer_Bは、Answer_Aが別のテーブルとのFK関係も必要とするという点でわずかに異なります。Answer_Bは、後でいくつかの特定の属性を必要とする場合もあります。Answer_Bをスーパークラスにし、Answer_Aサブクラスを作成するか、それを作成した場合でも、問題は発生します。

「リスク」は、Answer_AでもAnswer_Bでも同じです。サブタイプに関係なく、「回答」を参照する必要がある他のモデルもあります。これはどのように行うことができますか?サブタイプに関係なく、どのようにタイプを参照できますか?

更新:
私は結合操作を避けようとしていましたが、それができるとは思いません。すべての「回答」で「居住者」への参照を持ち、必要に応じてそれを無効にすることは価値がありますか?それとも、それは非常に悪い習慣と見なされますか?

4

2 に答える 2

18

一般的な関係が解決策のようです。しかし、それは事態をさらに複雑にします。

私にはそう思われる; モデル構造がすでに必要以上に複雑になっています。Answer単純に、3 つのモデルすべてを 1 つにマージします。こちらです:

  • Answer_Risk変更なしで動作します。
  • residentの場合は None (NULL) に設定できますAnswer_A
  • に応じて、さまざまな文字列表現を返すことができますresident == None。(つまり、同じ機能)

もう一つ; あなたの答えには、複数のリスクがある可能性がありますか? リスクがまったくないか、1 つしかない場合は、次の代替実装を検討する必要があります。

  • 1 対 1 の関係の使用
  • クラス内のフィールド (または任意の数のフィールド) としてのリスクの降格Answer

私の主な関心事は、データベースの構造でもパフォーマンスでもなく (これらの変更によりパフォーマンスが向上するはずですが)、コードの保守性です。

于 2008-12-15T08:24:54.443 に答える
8

私の直感は、基本クラスの抽象修飾子を削除することを提案することです。同じモデル構造が得られますが、回答は独自のテーブルになります。これの欠点は、これらが大きなテーブルである場合やクエリが複雑な場合、それに対するクエリが著しく遅くなる可能性があることです。

または、モデルをそのままにしておくこともできますが、ForeignKey to Answer を GenericForeignKey に置き換えます。モデル継承の構文糖衣で失うものは、クエリの速度が少し向上します。

抽象的な基本モデルを ForeignKey (または機能的に同じもの) で参照できるとは思えません。

于 2008-12-15T04:33:46.470 に答える