30

ForeignKeys on django には、参照されたオブジェクトが削除されたときの動作を指定するon_delete属性があります。ManyToManyFieldに似たものを取得する方法はありますか?

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

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

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

私は内部的ManyToManyFieldに 2 つの s を持つ別のモデルForeignKey(この場合は 1 つは家に、もう 1 つは人) に変換されることを知っているので、これを達成できるはずです。方法はありますか?through属性を新しいモデルに設定することは避けたいと思います。これにより、新しいテーブルが作成されるためです (古いテーブルを保持したい)。

編集: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 の新しいクラスを作成する以外に、これを行う方法はありますか?

4

3 に答える 3

8

最も賢明なことは、明示的なスルー テーブルを使用することだと思います。「これにより新しいテーブルが作成されるため(古いテーブルを保持したい)」と述べたのは承知しています。

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

これらの方法は両方ともここで説明されています: 「スルー」テーブルを django フィールドに追加し、南に移行しますか?

その定義に加えたい変更を考慮して、おそらく新しいテーブルを作成してからデータを移行するオプションを使用します。すべてのデータがまだそこにあること (および変更が意図したとおりであること) をテストしてから、古い中間テーブルを削除します。

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

于 2013-04-30T23:58:50.183 に答える