【问题标题】:Invoke Django Signal only if the record is newly created - Django仅当新创建记录时才调用 Django Signal - Django
【发布时间】:2022-10-20 14:38:25
【问题描述】:

我正在使用 Django post_save 信号,每当创建新记录时都会触发。每次发生保存操作时都会调用此信号。即使它有created 布尔字段,这个函数也一直在执行。

这里的问题是,在每次请求时,我都会更新Userlast_loginlast_active 字段。因此,对于每个请求,都会执行此信号。即使我们创建了布尔字段,函数调用也会发生。当我们一次有百万个请求时,这可能会导致性能影响。

我正在寻找解决方案,只有在 User 表中创建新记录时,才应执行信号。

示例代码:

@receiver(post_save, sender=User, dispatch_uid="call_method")
def call_method(sender, instance, created, **kwargs):
    print ('>>>>>>>>>> Signal Called ', instance)
    if created:
        print ('$$$$$$$$$$$ User created')

请帮助我找到更好的解决方案。

【问题讨论】:

  • 你能分享一下你想在信号中执行的指令类型吗?那里可能有一个快速而优雅的解决方案的机会

标签: python django django-models django-signals


【解决方案1】:

如果您在实例模型上调用 save ,则确实没有办法不挂接到信号中。 但是,如果您要更改更新用户实例的方式,则可以跳过该信号。

例如,这不会触发 post_save 事件

User.objects.filter(id=1).update(last_login=timestamp)

【讨论】:

    【解决方案2】:

    考虑将信号实现的逻辑移动到 User 类的 custom_save() 或重写默认的 save() 函数...

    诀窍是将您的指令放在正在保存的对象上存在主键的条件后面。 因此,当调用 custom_save() 或 save() 方法时,您背后的逻辑只会在第一条记录上执行(即创建)

    实际例子:

    class User(models.Model)
        ...
        email = models.Charfield(max_lenght=250, unique=True)
    
        # Overwrite Save method
        def save(self, *args, **kwargs):
            ...
    
            if not self.pk:   # Means that it is the first record of this object
                print (f'{self.email} User created')
    
            super().save(*args, **kwargs)
       
    

    【讨论】:

      【解决方案3】:

      您可以为此使用 pre_save 信号。

      pre_save:- 要在对象保存到数据库之前执行一些处理应用程序另一部分的代码,您必须使用 pre_save 信号。

      @receiver(pre_save, sender=User, dispatch_uid="call_method")
      def trigger_emails_to_employees(sender, instance, **kwargs):
          if not instance.pk:  # A newly created object (not denotes that the instance does not exists till now)
              print("Send email, trigger msgs, block previous records")
              print("Do whatever you want before creating the new object")
          ------------------------------
          if instance.pk:  # Invokes only when object is being edited.
              print("Trigger editing object things before the object get updated")
              print("Do whatever you want before editing the existing object")
      
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-12
        • 2021-08-06
        • 2012-07-25
        • 2018-10-13
        • 2020-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多