初始化新的mongoengine文档时调用某些函数

问题描述 投票:0回答:3

我正在尝试定义一个 Document 类,其中包含一些字段,这些字段的值在创建新文档时自动计算。 到目前为止,我已经通过扩展

__init__
函数成功做到了这一点,如下所示:

class URLDoc(Document):
    url = fields.URLField(requierd=True)
    domain = fields.StringField(required=True)
    screenshot = fields.ImageField(required=True, size=(600, 600, True), thumbnail=(100, 100, True))

    def __init__(self, *args, **kwargs):
        super(URLDoc, self).__init__(*args, **kwargs)
        self.domain = urlparse(self.url).netloc
        self.get_and_save_screenshot()


    def get_and_save_screenshot(self):
        '''Some code to get a screenshot of the website on self.url'''

        self.screenshot.put(screenshot_file)
        self.save()

这样我就可以通过调用

new_urldoc = URLDoc(url="some url")
然后调用
new_urldoc.save()
在 mongo 中创建新文档。

当我开始通过

URLDoc.objects.get(id="some id")
从 mongo 加载现有文档时,我意识到
__init__
函数将再次被触发,在文档中设置新数据(例如,截取新的屏幕截图)。

我想实现这个,但只有当文档是新的时候,我到处查找,找不到答案..

有没有办法在初始化new文档时调用某些函数而不是初始化现有文档?

python mongoengine
3个回答
2
投票

我一直在寻找类似的解决方案,过了一段时间我发现 MongoEngine 支持 Signals。在某些操作之前/之后,有多个信号可以与文档耦合:

  • 初始化
  • 节省
  • 删除

不幸的是不支持基于文档更新的信号,但解决方法是检查发送者文档是否有 ID。一个简单的代码片段 - 基于 MongoEngine 文档中的示例:

def update_modified(sender, document):
    if document.id: 
        document.modified = datetime.utcnow() # Will only be executed if the document has been already saved

1
投票

我让它工作了,我不知道这是否是一个解决方法,但我检查 init 函数上的

self._id
(仅在保存时创建 id),如果没有(意味着它是一个新文档),我设置了值。


0
投票

基于 mongoengine 的文档,如果

_created
kwarg 作为
True
传递,您可以确保正在从数据库加载文档,如下所示:

    def __init__(self, your_var, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print(kwargs)
        if not kwargs.get('_created', True):
            return  # Loaded from DB, No modification needed
        self.some_var = your_var
        # Initiate the brand new instance

注意:前面提到的这种方法确实有效,但仅适用于文档。 EmbeddedDocuments 没有

id
属性!

if self.id: 
    print("loaded from DB")
else:
    print("Brand new instance!")
© www.soinside.com 2019 - 2024. All rights reserved.