为了账号安全,请及时绑定邮箱和手机立即绑定

如何删除引用一个对象的所有嵌套对象?

如何删除引用一个对象的所有嵌套对象?

长风秋雁 2021-07-16 18:06:15
我有一个模型,它在几个模型中被设置为外键。现在,如果在这些模型中的任何一个中引用它,从模型中删除任何对象都会引发 ProtectedError。我想让用户在一次操作中删除包含所有受保护对象的对象。我可以通过简单地调用来删除第一层受保护的对象....    except ProtectedError as e    e.protected_objects.delete()....但是当protected_objects有自己的受保护对象时,操作失败并抛出另一个第二层ProtectedError。我想要实现的是,删除所有受保护的对象,一视同仁地删除它存在于哪一层。我知道这可能是一项危险的操作。但是我能否在没有复杂解决方案的情况下实现这一目标。提前致谢。源代码,我试图在其中执行 ajax 操作:try:    obj_list = model.objects.filter(pk__in=pk_list)    log_deletion(request, obj_list, message='Record Deleted')    obj_list.delete()    return JsonResponse({'success': True, 'status_message': '{0} record(s) has been deleted successfully.'.format(len(pk_list))})except ProtectedError as e:    e.protected_objects.delete()    return JsonResponse({'success': False, 'status_message': 'This operation cannot be executed. One or more objects are in use.'})
查看完整描述

2 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

通常,您可以使用循环:


...

except ProtectedError as e:

    obj = e.protected_objects

    while True:

        try:

            obj.delete()

        except ProtectedError as e:

            obj = e.protected_objects

        else:

            break

...

要记录错误发生在哪个层,您可以添加一个计数器:


from itertools import count


obj_list = model.objects.filter(pk__in=pk_list)

for layer in count():

    try:

        log_deletion(request, obj_list, message='Record Deleted in layer {}'.format(layer))

        obj_list.delete()

    except ProtectedError as e:

        obj_list = e.protected_objects

    else:

        if layer == 0:

            return JsonResponse({'success': True, 'status_message': '{0} record(s) has been deleted successfully.'.format(len(pk_list))})

        else:

            return JsonResponse({'success': False, 'status_message': 'This operation cannot be executed. One or more objects are in use.'})



查看完整回答
反对 回复 2021-07-28
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

看起来您可能不想使用on_delete=models.PROTECT外键的定义。您是否考虑过将 on delete 更改为使用CASCADE?如果使用级联,则无需遍历依赖项即可先删除它们。

而不是:

class OtherModel(models.Model):
    link = models.ForeignKey("Link", on_delete=models.PROTECT)

您可以像这样定义模型:

class OtherModel(models.Model):
    link = models.ForeignKey("Link", on_delete=models.CASCADE)

当从管理员中删除使用CASCADE中间页面的模型时,将显示列出也将被删除的所有依赖对象。


查看完整回答
反对 回复 2021-07-28
  • 2 回答
  • 0 关注
  • 181 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号