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

时间:2013-02-10 02:34:32

标签: django

通过on_delete option, Django provides various alternatives了解如何处理具有被删除对象的外键的对象。

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

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)

1 个答案:

答案 0 :(得分:4)

Django提供的选项(CASCADEPROTECT等)都是1.5的函数 - here's where they're defined

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