Выпуск встроенных документов с помощью MongoEngine

Я использую MongoDB с Flask-MongoEngine в качестве компонента ORM для моего веб-приложения.

я структурировал схему пользовательского документа следующим образом:

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)

однако, при создании нового пользователя (я оставил линии...):

def create_new_user(resp):
    newUser = User()
    ....
    newUser.settings.default_cal = resp['calendar']
    ....
    newUser.save()
    return

я сталкиваюсь с этой ошибкой:

AttributeError: объект "NoneType" не имеет атрибута "default_cal"

мне кажется, что я неправильно использую встроенные документы MongoEngines, но я этого не делаю знаю, где я ошибаюсь.

любая помощь была бы весьма признательна!

1 ответов


Ну, вам просто нужно создать встроенный объект документа определенного класса, а затем использовать его с основным классом документа, например:

new_user = User()
user_settings = UserSettings()
user_settings.default_cal = resp['calendar']
new_user.settings = user_settings
# more stuff
new_user.save()

Примечание: создание нового объекта только для основного документа не создает автоматически соответствующий внедренный объект(ы) документа, но при чтении данных, конечно, дело другое.

Edit:

Как tbicr упоминает ниже, мы также можем сделать это:

settings = db.EmbeddedDocumentField(UserSettings, default=UserSettings)

пока объявляя поле, таким образом, нам не нужно будет создавать объект, как указано в первом примере.