MongoEngine - 信号

信号是由发送者对象派发的事件,任何数量的接收者对象都可以订阅此类事件。 信号接收者可以订阅特定的发送者,也可以接收来自多个发送者的信号。

在 MongoEngine 中,信号处理由 blinker 库支持,这意味着您需要使用 pip 实用程序安装它。 mongoengine.signals 模块具有以下信号的定义 −

pre_init 在创建新的 Document 或 EmbeddedDocument 实例期间调用,并在收集构造函数参数之后但在对它们进行任何其他处理之前执行。
post_init 在完成对新 Document 或 EmbeddedDocument 实例的所有处理后调用。
pre_save 在执行任何操作之前在 save() 中调用。
pre_save_post_validation 在验证发生之后但在保存之前在 save() 中调用。
post_save 在大多数操作(验证、插入/更新)成功完成后在 save() 中调用。 传递一个额外的布尔关键字参数以指示保存是插入还是更新。
pre_delete 在尝试删除操作之前在 delete() 中调用。
post_delete 成功删除记录后在 delete() 中调用。
pre_bulk_insert 在验证要插入的文档之后但在写入任何数据之前调用。
post_bulk_insert 在批量插入操作成功后调用。 加载的附加布尔参数将文档的内容标识为 True 时的 Document 实例或 False 时插入记录的主键值列表。

然后将事件处理函数附加到 Document 类。 请注意,EmbeddedDocument 仅支持 pre/post_init 信号。 pre/post_save 等,应仅附加到 Document 类。

您还可以使用装饰器快速创建多个信号并将它们附加到您的 Document 或 EmbeddedDocument 子类作为类装饰器。

在下面的示例中,作为信号处理程序的演示,我们还使用了 Python 的标准库模块 - logging,并将日志级别设置为 debug。

from mongoengine import *
from mongoengine import signals
import logging
logging.basicConfig(level=logging.DEBUG)

然后我们编写一个文档类,以便在 newdb 数据库中创建相应的集合。 在该类内部,定义了两个类方法 pre_save() 和 post_save() 方法,它们旨在在将文档保存到 Author 集合之前和之后调用。

class Author(Document):
   name = StringField()
   
   def __unicode__(self):
      return self.name

   @classmethod
   def pre_save(cls, sender, document, **kwargs):
      logging.debug("Pre Save: %s" % document.name)

   @classmethod
   def post_save(cls, sender, document, **kwargs):
      logging.debug("Post Save: %s" % document.name)
      if 'created' in kwargs:
         if kwargs['created']:
            logging.debug("Created")
         else:
            logging.debug("Updated")

这两个类方法都是用类名、发送者对象和文档的参数定义的,带有可选的关键字参数列表。

最后,我们注册信号处理程序。

signals.pre_save.connect(Author.pre_save, sender=Author)
signals.post_save.connect(Author.post_save, sender=Author)

当我们创建一个 Document 子类的实例时,控制台日志将显示保存前和保存后信号正在由相应的事件处理程序处理。

Author(name="Lathkar").save()

Python控制台上报日志如下 −

DEBUG:root:Pre Save: Lathkar
DEBUG:root:Post Save: Lathkar
DEBUG:root:Created