Domanda

Sto costruendo un'applicazione che utilizza Django MongoDB e MongoEngine per memorizzare i dati. Per presentare una versione semplificata del mio problema, dico io voglio avere due classi: Utente e Pagina. Ogni pagina dovrebbe associarsi con un utente e ogni utente una pagina.

from mongoengine import *

class Page(Document):
    pass

class User(Document):
    name = StringField()
    page = ReferenceField(Page)

class Page(Document):
    content = StringField()
    user = ReferenceField(User)

(Si noti che pagina deve essere definito prima dell'utente. Se mi manca un modo Pythonic per gestire le dipendenze circolari, fatemelo sapere.) Ogni documento può essere creato e salvato bene, ma l'assegnazione di una pagina a un utente genera un errore .

u = User(name='Jeff')
u.save()
p = Page(content="I'm a page!")
p.save()
p.user = u
p.save()
u.page = p
u.save()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build\bdist.win32\egg\mongoengine\document.py", line 71, in save
  File "build\bdist.win32\egg\mongoengine\base.py", line 303, in validate
mongoengine.base.ValidationError: Invalid value for field of type "ReferenceField"

Qualcuno può spiegare perché viene gettata questa eccezione, quello che sto facendo male, e come posso evitarlo?

È stato utile?

Soluzione

Questa è la soluzione corretta:

from mongoengine import *

class User(Document):
    name = StringField()
    page = ReferenceField('Page')

class Page(Document):
    content = StringField()
    user = ReferenceField(User)

Usa virgolette singole ( 'Pagina') per indicare le classi che non sono ancora stati definiti.

Altri suggerimenti

La risposta di Drew è il modo migliore in questo caso, ma volevo dire che è anche possibile utilizzare un GenereicReferenceField:

from mongoengine import *

class User(Document):
    name = StringField()
    page = GenericReferenceField()

class Page(Document):
    content = StringField()
    user = ReferenceField(User)

Ma ancora una volta, per il vostro problema specifico, andare con il nome della classe tra virgolette singole.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top