3

概念的に私が欲しいのはこれです:

class Child:
    guardians = models.ManyToManyField(Guardian)

class Guardian:
    children = models.ManyToManyField(Child)

申請は学校です。1 人の親 (保護者) は複数の子供を持つことができ、どの子供も複数の保護者を持つことができます。現在、C++ のように Python で前方宣言を行うことはできません。

これを行うための最もクリーンで最良の方法は何ですか? これらの接続を表すために 3 番目の「関係」クラスが必要ですか (これが私が目指しているものです)。しかし、車輪を再発明する前に、私は尋ねたかった. これは簡単なはずです...

4

2 に答える 2

6

問題を理解しているかどうかわかりません。

これを行うことにより:

class Child:
    guardians = models.ManyToManyField('Guardian', related_name='children')

class Guardian:
    .... some other fields
    # children = models.ManyToManyField(Child)  <--- not needed

「子供は多くの保護者を持つことができ、保護者は多くの子供を持つことができる」と言っているようなものです。両方のモデルで宣言する必要はありません。

また、3番目の(中間)テーブルは、とにかく舞台裏でdjangoによって作成されます。これは、RDBMS で ManyToMany 関係をモデル化する方法だからです。

中間モデルを明示的に作成する唯一の理由は、特定の多対多の関係を説明する追加情報を追加する必要がある場合です。すなわち

class Child:
    guardians = models.ManyToManyField('Guardian', 
        through='ChildGuardianMembership', related_name='children')

class Guardian:
    .... some other fields

class ChildGuardianMembership:
    child = models.ForeignKey(Child)
    guardian = models.ForeignKey(Guardian)
    created_at = models.DateTimeField(auto_now_add=True) # When was this relationship established?

その場合、明示的な中間モデルを宣言したため、これがガーディアンと子の間の関係を作成するときに使用するモデルであることに注意する必要があります。

例えば

ChildGuardianMembership.objects.create(child=child_inst, guardian=guardian_inst)

many2many リレーションシップ (上記のように) にフィールドを追加する方法については、こちらで説明しています

于 2012-06-05T09:36:53.130 に答える
0

これが明示的に無効にされていない限り、リレーションはすでに双方向です。

于 2012-06-05T04:05:40.777 に答える