9

on_delete オプションを通じて、Django は、削除されるオブジェクトへの外部キーを持つオブジェクトをどうするかについて、さまざまな代替手段を提供します。

同様のことを行う方法があるかどうか疑問に思っていますが、条件付きです。これがシナリオです。私は Django 1.5 の新しいカスタム User モデルを利用しており、すべてのユーザーが Site への ForeignKey を持っています。そのようです:

class TenantSiteUser(AbstractUser):
  site = models.ForeignKey(Site, null=True)

サイトが削除された場合、そのサイトにリンクされているすべての非スーパーユーザー (つまり、KASKADE のような動作) を削除したいと思います。しかし、スーパーユーザーの場合は、ユーザーのサイトを null (つまり、SET_NULL) に設定し、存在し続けることを好みます。これは、おそらく私または私が一緒に働いている誰かであり、意図せずに自分自身を削除したくない傾向があるためです。

このタイプの on_delete 動作を手動でチェックして実装するためにオーバーライドできるものはありますか?

編集: @Kevin の回答と既存のハンドラーがどのように機能するかについてのいくつかの研究に基づいて、私のために働いたコードは次のとおりです。

def NULLIFY_SUPERUSERS_ELSE_CASCADE(collector, field, sub_objs, using):
    superusers = []
    for user in sub_objs:
        if user.is_superuser:
            sub_objs = list(sub_objs)
            sub_objs.remove(user)
            superusers.append(user)

    CASCADE(collector, field, sub_objs, using)
    if len(superusers):
        collector.add_field_update(field, None, superusers)

class TenantSiteUser(AbstractUser):
    site = models.ForeignKey(Site, null=True, on_delete=NULLIFY_SUPERUSERS_ELSE_CASCADE)
4

1 に答える 1

7

Django が提供するオプション (CASCADEなどPROTECT) はすべて関数です。ここでは、1.5 用に定義されています。

私はそれをテストしていませんが、独自のNULL_OR_CASCADE関数を記述して、それをフィールドの on_delete 引数として渡すことができるはずです。

于 2013-02-10T03:24:19.447 に答える