MongoEngine意外更改字段值

MongoEngine意外更改字段值,mongoengine,Mongoengine,我试图在mongoengine文档类中模拟一个序列。我已经覆盖了init函数以查找下一个连续值,并在文档中对其进行了设置。由于某种原因,每次我添加另一个对象或调用objects.all()函数时,该数字都会增加。谁能告诉我发生了什么事 代码如下: from mongoengine import connect, Document, StringField, IntField class MyDocument(Document): number = IntField(unique=Tru

我试图在mongoengine文档类中模拟一个序列。我已经覆盖了init函数以查找下一个连续值,并在文档中对其进行了设置。由于某种原因,每次我添加另一个对象或调用objects.all()函数时,该数字都会增加。谁能告诉我发生了什么事

代码如下:

from mongoengine import connect, Document, StringField, IntField

class MyDocument(Document):
    number = IntField(unique=True, required=True)
    name = StringField()

    def __init__(self, *args, **kwargs):
        super(MyDocument, self).__init__(*args, **kwargs)
        num_objs = MyDocument.objects.count()
        self.number = 1 if num_objs == 0 else num_objs + 1

connect('test-database')
MyDocument.drop_collection()

pj = MyDocument(name='foo').save()
print((pj.number, pj.name))  # pj.number is 1?
print([(pj.number, pj.name) for pj in MyDocument.objects.all()]) # pj.number is 2?
pj = MyDocument(name='bar').save()
print([(pj.number, pj.name) for pj in MyDocument.objects.all()]) # both pj.numbers are 3?
哪些产出:

(1, 'foo')
[(2, 'foo')]
[(3, 'foo'), (3, 'bar')]

我仍然不确定是什么问题导致了副作用,但我能够使用pre_save信号修复它:

from mongoengine import connect, signals, Document, StringField, IntField

class MyDocument(Document):
    number = IntField(unique=True, required=True)
    name = StringField()

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        num_objs = MyDocument.objects.count()
        document.number = 1 if num_objs == 0 else num_objs + 1
MongoEngine提供了支持该用例的工具。它应该适合你的需要

至于为什么您的实现不正确,这是因为每次构造新对象时都会调用构造函数,如中所示

MyDocument(name='whatever')


但是每次从数据库中提取对象时,构造函数也被称为(例如
MyDocument.objects.all()
或MyDocument.objects.first()),实际上在幕后,pymongo提供了一个dict,MongoEngine通过使用构造函数将其转换为
MyDocument
实例

忘了提到,使用:Windows10、Python 3.7.1、mongoengine 0.18.2和mongodb服务器4.2。