2013-07-26 18 views
5

Sto utilizzando MongoDB con Flask-MongoEngine come componente ORM alla mia app Web.Problema dei documenti incorporati con MongoEngine

ho strutturato il documento schema utente in questo modo:

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) 

Tuttavia, quando si crea un nuovo utente di questo tipo (le linee che ho lasciato fuori ...):

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

corro in questo errore:

AttributeError: oggetto 'NoneType' non ha un attributo 'default_cal'

Mi sembra di non utilizzare correttamente i documenti incorporati MongoEngines, ma non so dove sto andando male.

Qualsiasi aiuto sarebbe molto apprezzato!

risposta

7

Beh non resta che creare un oggetto documento incorporato della classe particolare e quindi utilizzarlo con la classe documento principale, in questo modo:

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

Nota: La creazione di un nuovo oggetto solo per il documento principale , non crea automaticamente gli oggetti documento incorporato corrispondenti, ma durante la lettura dei dati, il caso è diverso.

Edit:

Come tbicr menzioni di seguito, possiamo anche fare questo:

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

pur dichiarando il campo, in questo modo non sarà necessario creare l'oggetto come indicato nella primo esempio

+7

Oppure creare il documento incorporato per impostazione predefinita: 'db.EmbeddedDocumentField (UserSettings, default = UserSettings)'. – tbicr

+0

@tbicr ah, è bello, grazie, modifica la risposta. –

+1

Grazie! Questo è esattamente quello che dovevo sapere. Tutto funziona come previsto ora! –

Problemi correlati