django ManyToManyField と on_delete 質問する

django ManyToManyField と on_delete 質問する

ForeignKeydjangoのsには属性がある削除時参照オブジェクトが削除されたときの動作を指定します。同様のものを取得する方法はありますか?多対多フィールド?

次のようなモデルがあるとします

class House(models.Model):
    owners = models.ManyToManyField(Person)

デフォルトの動作はカスケードなので、たまたま家を所有している人を削除すると、その人は所有者から消えてしまいます (つまり、明らかに、その人はもはや家を所有していません)。 私が望むのは、人が所有者である場合は削除できないようにすることです。 つまり、 が欲しいのですon_delete=models.PROTECT。 これは可能ですか?

内部的にはManyToManyField2つのs(この場合は1つはhouse、もう1つはperson)を持つ別のモデルに変換されるのでForeignKey、これを実現できるはずです。何かいいアイデアはありますか?を通して属性を新しいモデルに追加しないでください。これにより新しいテーブルが作成されるためです (古いテーブルは保持したいです)。

編集: Django が適切な m2m モデルを作成する場所を追跡しました:

def create_many_to_many_intermediary_model(field, klass):
    from django.db import models
    # ... 
    # Construct and return the new class.
    return type(name, (models.Model,), {
        'Meta': meta,
        '__module__': klass.__module__,
        from_: models.ForeignKey(klass,
                                 related_name='%s+' % name,
                                 db_tablespace=field.db_tablespace),
        to: models.ForeignKey(to_model,
                              related_name='%s+' % name,
                              db_tablespace=field.db_tablespace)
    })

関連する行は

to: models.ForeignKey(to_model,
                      related_name='%s+' % name,
                      db_tablespace=field.db_tablespace)

そうであってほしい

to: models.ForeignKey(to_model,
                      related_name='%s+' % name,
                      db_tablespace=field.db_tablespace,
                      on_delete=models.PROTECT)

全体にモンキーパッチを適用して ManyToManyField の新しいクラスを作成する以外に、これを行う方法はありますか?

ベストアンサー1

最も賢い方法は、明示的なスルー テーブルを使用することだと思います。「新しいテーブルが作成されるため (古いテーブルは保持したい)」、そうしたくないとおっしゃっていることは承知しています。

おそらく、あなたの懸念は、所有しているデータが失われることではないかと思います。South を使用している場合は、既存の自動中間テーブルを明示的なテーブルに簡単に「変換」できます。または、完全に新しいテーブルを作成してから、古いテーブルを削除する前に、既存のデータを新しいテーブルに移行することもできます。

これら両方の方法については、ここで説明します。Django フィールドに「スルー」テーブルを追加して、South に移行しますか?

定義に加えたい変更を考慮すると、新しいテーブルを作成してからデータを移行するというオプションを選択することになるでしょう。すべてのデータがまだ存在していること (および変更が期待どおりに機能していること) をテストして確認してから、古い中間テーブルを削除します。

これらのテーブルはどちらも行ごとに 3 つの整数しか保持しないことを考慮すると、家や所有者が多数いる場合でも、これは非常に扱いやすい作業になる可能性があります。

おすすめ記事