2013-07-26 13 views
5

Używam MongoDB z Flask-MongoEngine jako mojego komponentu ORM do mojej aplikacji internetowej.Problem dotyczący osadzonych dokumentów z MongoEngine

Mam skonstruowany schemat dokument użytkownika tak:

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) 

Jednak Podczas tworzenia nowego użytkownika tak (mam pozostawione na liniach ...):

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

biegnę do tego błędu:

AttributeError: obiekt 'NoneType' nie ma atrybutu 'default_cal'

Wydaje mi się, że nie używam poprawnie dokumentów wbudowanych w MongoEngines, ale nie wiem, gdzie idę źle.

Każda pomoc będzie bardzo ceniona!

Odpowiedz

7

No po prostu trzeba utworzyć obiekt osadzony dokument z danej klasy, a następnie używać go z głównej klasy dokumentu, tak jak poniżej:

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

Uwaga: Tworzenie nowego obiektu tylko dla dokumentu głównego , nie tworzy automatycznie odpowiedniego obiektu (obiektów) wbudowanego dokumentu, ale podczas odczytywania danych oczywiście sprawa jest inna.

Edit:

Jak tbicr wspomina poniżej, możemy również to zrobić:

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

podczas deklarowania pole, w ten sposób, że nie będzie trzeba utworzyć obiekt, jak podano w pierwszy przykład.

+7

Możesz też utworzyć domyślnie dokument osadzony: 'db.EmbeddedDocumentField (UserSettings, default = UserSettings)'. – tbicr

+0

@tbicr ah, to miłe, dziękuję, edytowanie odpowiedzi. –

+1

Dziękujemy! Dokładnie to musiałem wiedzieć. Wszystko działa zgodnie z oczekiwaniami! –