Mongoengine 简明教程

MongoEngine - Signals

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

Signals are events dispatched by a sender object, any number of receiver objects can subscribe to such events. A signal receiver can subscribe to a specific sender or may receive signals from many senders.

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

In MongoEngine, signal handling is supported by blinker library, which means you need to install it using pip utility. The mongoengine.signals module has the definitions of following signals −

pre_init

Called during the creation of a new Document or EmbeddedDocument instance and executed after the constructor arguments have been collected but before any additional processing has been done to them.

post_init

Called after all processing of a new Document or EmbeddedDocument instance has been completed.

pre_save

Called within save() prior to performing any actions.

pre_save_post_validation

Called within save() after validation has taken place but before saving.

post_save

Called within save() after most actions (validation, insert/update) have completed successfully. An additional Boolean keyword argument is passed to indicate if the save was an insert or an update.

pre_delete

Called within delete() prior to attempting the delete operation.

post_delete

Called within delete() upon successful deletion of the record.

pre_bulk_insert

Called after validation of the documents to insert, but prior to any data being written.

post_bulk_insert

Called after a successful bulk insert operation. An additional Boolean argument, loaded, identifies the contents of documents as either Document instances when True or a list of primary key values for the inserted records if False.

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

An event handler function is then attached to Document class. Note that EmbeddedDocument only supports pre/post_init signals. pre/post_save, etc., should be attached to Document’s class only.

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

You can also use a decorator to quickly create a number of signals and attach them to your Document or EmbeddedDocument subclasses as class decorators.

在以下示例中,用作信号处理程序的演示,我们还使用 Python 的标准库模块——记录并设置记录级别以进行调试。

In the following example, used as demonstration of signal handlers, we also use Python’s standard library module – logging and set the logging level to debug.

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

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

We then write a document class so that corresponding collection is created in newdb database. Inside the class, two class mehods pre_save() and post_save() methods are defined which are intended to be invoked before and after a document is saved in Author collection.

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")

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

Both the class methods are defined with arguments for classname, sender object and document with optional list of keyword arguments.

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

Finally, we register the signal handlers.

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

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

As we create an instance of Document subclass, the console log will show the pre and post save signals being processed by respective event handlers.

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

Python 控制台按如下所示报告日志 −

Python console reports the log as shown below −

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