可以在Django中做条件ForeignKey.on_delete吗? [英] Possible to do conditional ForeignKey.on_delete in Django?

查看:102
本文介绍了可以在Django中做条件ForeignKey.on_delete吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过 on_delete选项, Django提供了多种替代方法处理具有要删除的对象的外键的对象。

Through the on_delete option, Django provides various alternatives for what to do with objects that have a foreign key to an object that is being deleted.

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

I'm wondering if there is a way I could do something similar, but conditionally. Here's the scenario. I am utilizing Django 1.5's new custom User model and all my users have a ForeignKey to Site. Like so:

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

如果网站被删除,则我希望删除链接到该网站的所有非超级用户(即类似KASKADE的行为),因为它们的存在现在毫无意义。但是,如果是超级用户,则我希望将用户的网站设置为空(即SET_NULL),并让他们保持现有状态,因为这可能是我或与我合作的人,而且我们不希望无意间删除自己。

If a site is deleted, then I'd prefer to delete all the non-superusers linked to that site (i.e., KASKADE-like behavoir), since their existence is now meaningless. But if its a superuser, I'd prefer to just set the user's site to null (i.e., SET_NULL) and let them keep existing, since that's probably me or someone I work with and we tend to not want to unintentionally delete ourselves.

是否可以覆盖某些内容以手动执行检查并实现这种on_delete行为?

Is there something I can override to manually do a check and implement this type of on_delete behavior?

EDIT :根据@Kevin的答案以及对现有处理程序的工作方式的研究,以下是最终对我有用的代码:

Here's the code that ended up working for me, based on @Kevin's answer and some study of how the existing handlers work:

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)


推荐答案

Django提供的选项( CASCADE 保护等)都是功能-在这里定义它们为1.5。

The options Django provides (CASCADE, PROTECT etc.) are all functions - here's where they're defined for 1.5.

我尚未对其进行测试,但是应该可以编写自己的 NULL_OR_CASCADE 函数并将其传递给作为您字段的on_delete参数。

I haven't tested it, but it should be possible to write your own NULL_OR_CASCADE function and pass that in as your field's on_delete argument.

这篇关于可以在Django中做条件ForeignKey.on_delete吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆