嵌入式文档与MongoEngine有关

Tim*_*eno 6 python mongodb mongoengine flask flask-mongoengine

我使用带有Flask-MongoEngine的MongoDB作为我的网络应用程序的ORM组件.

我已经构建了User文档架构,如下所示:

from ..core import db

class UserComics(db.EmbeddedDocument):
    favorites = db.SortedListField(db.StringField(), default=None)

class UserSettings(db.EmbeddedDocument):
    display_favs = db.BooleanField(default=False)
    default_cal = db.StringField(default=None)
    show_publishers = db.ListField(db.StringField(), default=None)

class UserTokens(db.EmbeddedDocument):
    refresh_token = db.StringField(default=None)
    access_token = db.StringField(default=None)
    expire_time = db.StringField(default=None)

class User(db.Document, UserMixin):
    # Save User document to this collection
    meta = {'collection': 'users_test'}

    userid = db.StringField()
    full_name = db.StringField()
    first_name = db.StringField()
    last_name = db.StringField()
    gender = db.StringField()
    birthday = db.StringField()
    email = db.EmailField()
    friends = db.ListField(db.StringField())
    date_creation = db.DateTimeField()
    last_login = db.DateTimeField()
    favorites = db.EmbeddedDocumentField(UserComics)
    settings = db.EmbeddedDocumentField(UserSettings)
    tokens = db.EmbeddedDocumentField(UserTokens)
Run Code Online (Sandbox Code Playgroud)

但是,在创建这样的新用户时(我已经省略了行...):

def create_new_user(resp):
    newUser = User()
    ....
    newUser.settings.default_cal = resp['calendar']
    ....
    newUser.save()
    return
Run Code Online (Sandbox Code Playgroud)

我遇到这个错误:

AttributeError:'NoneType'对象没有属性'default_cal'

在我看来,我没有正确使用MongoEngines Embedded文档,但我不知道我哪里出错了.

任何帮助将不胜感激!

boo*_*dev 8

那么你只需要创建特定类的嵌入式文档对象,然后将其与主文档类一起使用,如下所示:

new_user = User()
user_settings = UserSettings()
user_settings.default_cal = resp['calendar']
new_user.settings = user_settings
# more stuff
new_user.save()
Run Code Online (Sandbox Code Playgroud)

注意:仅为主文档创建新对象,不会自动创建相应的嵌入式文档对象,但在读取数据时,情况则不同.

编辑:

正如下面提到的那样,我们也可以这样做:

settings = db.EmbeddedDocumentField(UserSettings, default=UserSettings)
Run Code Online (Sandbox Code Playgroud)

在声明字段时,我们不需要像第一个例子中那样创建对象.

  • 或者默认创建嵌入式文档:`db.EmbeddedDocumentField(UserSettings,default = UserSettings)`. (8认同)