Выпуск встроенных документов с помощью 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)
пока объявляя поле, таким образом, нам не нужно будет создавать объект, как указано в первом примере.