【问题标题】:Should I prefer one general signal instead of multiple specific ones?我应该更喜欢一个通用信号而不是多个特定信号吗?
【发布时间】:2017-12-07 18:28:50
【问题描述】:

当用户创建产品时,在调用super(Product,self).save(*args,**kwargs)之前,必须在save()方法中完成多个操作。

我不确定是否应该只使用一个pre_save 信号来执行所有这些操作,或者最好分别为每个操作创建一个信号。

简单示例(我将用信号替换 save 覆盖):

class Product(..):
    def save(...):
        if not self.pk:
            if not self.category:
                self.category = Category.get_default()
            if not self.brand:
                self.brand = 'NA'
        super(Product,self).save(*args,**kwargs)
        ...

所以

@receiver(pre_save,sender=Product)
def set_attrs(instance,**kwargs):
    if kwargs['created']:
        instance.category = Category.get_default()
        instance.brand = 'NA'

@receiver(pre_save,sender=Product)
def set_category(instance,**kwargs):
    if kwargs['created']:
        instance.category = Category.get_default()

@receiver(pre_save,sender=Product)
def set_brand(instance,**kwargs):
    if kwargs['created']:
        instance.brand = 'NA'

这只是一个简单的例子。在这种情况下,一般的set_attrs 可能就足够了,但是还有更复杂的情况,例如为user 创建userprofileuserplan 等。

对此是否有一些最佳实践建议?你的意见?

【问题讨论】:

  • 我会说为了可维护性最好将它们分开。但我通常尽量避免使用信号,而是使用管理器方法等。

标签: python django django-models django-signals


【解决方案1】:

简而言之,可以将其作为一条建议指出,

如果对一个模型实例的操作影响另一个模型,则信号是最干净的方式。这是一个可以使用信号的示例,因为如果您知道我的意思,您可能希望避免从another_modelsave() 方法中调用some_model.save()

举例说明,当覆盖save() 方法时,常见的任务是从模型中的某些字段创建 slug。如果您需要在多个模型上实现此过程,那么使用pre_save 信号将是一个好处,而不是在每个模型的save() 方法中进行硬编码。

此外,在批量操作中,不一定会调用这些信号和方法。

来自文档,

在批量操作中不调用重写的模型方法

请注意,当使用 QuerySet 批量删除对象或作为级联删除的结果时,不一定会调用对象的 delete() 方法。为确保执行自定义删除逻辑,您可以使用 pre_delete 和/或 post_delete 信号。

不幸的是,在批量创建或更新对象时没有解决方法,因为没有调用 save()、pre_save 和 post_save。

更多参考,

【讨论】:

    猜你喜欢
    • 2010-12-30
    • 2013-08-21
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多