【问题标题】:Django delete without calling signalsDjango删除而不调用信号
【发布时间】:2014-04-15 07:23:42
【问题描述】:

我将信号用于在删除、保存、更新对象等时应始终完成的事情。但是,有时我不想调用我的保存信号,所以我使用

Model.objects.filter(id=instance.id).update(field=value)

代替实例的save方法:

instance.save()

在删除对象的情况下,也有一些时候我不想调用删除信号,但我还没有找到避免调用它们的方法。有办法吗??

更新:

我正在使用 django 1.6.2 并像这样调用删除方法:

Model.objects.filter(id=instance.id).delete()

在查询集上仍然调用删除信号。

【问题讨论】:

    标签: django django-models django-signals


    【解决方案1】:

    不安全未记录的方式可能会在版本之间发生变化,并且可能会导致难以调试的意外后果

    这是一个你可能不想使用的 hack,但是....这是可能的。

    qs = Model.objects.filter(id=instance.id)
    qs.order_by().select_related(None)._raw_delete(qs.db)
    

    如果您有任何与此相关的对象,它可能会因数据库错误而失败,因为 Django 不会自动删除记录

    【讨论】:

    • 刚刚在 django 3.1 上尝试过——它最初由于来自另一个表的外键引用而失败;在我移除另一个对象后,第二次尝试并成功了。如果它不起作用,我会求助于 SQL。
    【解决方案2】:

    在您不想调用信号的地方,您必须断开它们,运行您的代码,然后重新连接它们。你可以看看 mute_signal 装饰器是如何在 FactoryBoy 中实现的,或者只是使用(但它基本上是用于 django 测试的)

    【讨论】:

      【解决方案3】:

      你可以这样做。

      Model.objects.filter(id=instance.id).delete()
      

      【讨论】:

      【解决方案4】:

      尝试使用原始 SQL,不要抗拒它。它始终是您可以使用的强大终极武器。

      from django.db import connection
      
      with connection.cursor() as cursor:
          cursor.execute(f'DELETE from tbl_model where id={instance.id}')
      

      【讨论】:

        猜你喜欢
        • 2015-02-18
        • 1970-01-01
        • 2021-12-15
        • 1970-01-01
        • 2017-10-10
        • 2015-09-24
        • 2018-11-10
        • 2021-03-04
        • 1970-01-01
        相关资源
        最近更新 更多