可以在Django中做条件ForeignKey.on_delete吗?

Ben*_*rts 5 django

通过on_delete选项,Django为具有要删除对象的外键的对象提供了多种选择

我想知道是否有办法可以有条件地做类似的事情。这是场景。我正在使用Django 1.5的新自定义用户模型,并且我所有的用户都有一个ForeignKey到Site。像这样:

class TenantSiteUser(AbstractUser):
  site = models.ForeignKey(Site, null=True)
Run Code Online (Sandbox Code Playgroud)

如果删除了站点,那么我宁愿删除链接到该站点的所有非超级用户(例如,类似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)
Run Code Online (Sandbox Code Playgroud)

Kev*_*vin 7

Django 提供的选项 ( CASCADE, PROTECTetc.) 都是函数 -这是它们在1.5 中定义的地方

我还没有测试过,但应该可以编写自己的NULL_OR_CASCADE函数并将其作为字段的 on_delete 参数传递。