【问题标题】:Stop signal send trigger for specific Sender特定 Sender 的停止信号发送触发
【发布时间】:2019-11-16 03:19:04
【问题描述】:

我正在使用 Django 2.2

在我的应用程序中,有一个共享用户功能,每个共享用户都添加到 User 模型中,is_shared 字段设置为 True

共享用户链接到 SharedUser 模型中的用户,例如

class SharedUser(models.Model)
    user = models.ForeignKey(User, on_delete=models.CASCASE, related_name='owner_user')
    shared_user = models.ForeignKey(User, on_delete=models.CASCASE, related_name='shared_user')

在从 SharedUser 模型中删除记录时,我还必须从 User 模型中删除链接的 shared_user 记录。为此,我使用post_signal 接收器。

receivers.py

@receiver(post_delete, sender=SharedUser, dispatch_uid='post_delete_shared_user')
def post_delete_shared_user(sender, instance, *args, **kwargs):
    try:
        if instance and instance.shared_user:
            owner = instance.user
            instance.shared_user.delete()
    except:
        pass

并且接收器在 app.py 配置中加载

class SharedUsersConfig(AppConfig):
    name = 'shared_users'

    def ready(self):
        from . import receivers

现在,每当删除 SharedUser 模型中的一条记录时,它都会进行大量 SQL 查询。

import receiversapps.py 文件中删除时。

当接收者用于删除关联用户时,会进行更多的 SQL 查询。

在我的用例中,shared_user 没有与 SharedUser 模型以外的任何其他模型相关联。

  1. 如何减少删除用户的查询?
  2. 我能否仅在这种情况下删除用户时禁用发送信号?因为shared_user 与任何其他模型无关。

【问题讨论】:

    标签: django django-models django-signals


    【解决方案1】:

    问题出在您的 shared_user = models.ForeignKey(User, on_delete=models.CASCASE, related_name='shared_user') 尤其是 on_delete 属性中。

    每次删除 User 记录时,所有相关的 SharedUser 记录也会被删除。

    为防止删除,您应该使用on_delete=models.SET_NULL

    【讨论】:

    • 我相信 on_delete 适用于关联的 User 模型。意思是,当用户从 User 模型中删除时,它将级联链接的shared_user。但它不能以相反的方式工作。如果是这样,那么禁用信号接收器不会只进行 6 次 SQL 查询。
    • 我认为问题存在一个奇怪的循环。每次你删除SharedUser,在一个信号中你删除User,级联也删除SharedUser,触发删除信号,再次删除User和...循环。您必须记住,在 model.delete() 上不需要提交 sql.DELETE,并且在您的记录被真正删除之前,您将遍历循环。也许您正在寻找处理提交的数据 (docs.djangoproject.com/en/2.2/topics/db/transactions/…)
    猜你喜欢
    • 1970-01-01
    • 2020-04-08
    • 2014-07-09
    • 2021-04-27
    • 1970-01-01
    • 2019-04-25
    • 2016-05-02
    • 2011-04-03
    • 2016-03-15
    相关资源
    最近更新 更多