Question

Je construis une application Django qui utilise MongoDB et MongoEngine pour stocker des données. Pour présenter une version simplifiée de mon problème, que je veux avoir deux classes: l'utilisateur et la page. Chaque page doit s'associer à un utilisateur et chaque utilisateur une page.

from mongoengine import *

class Page(Document):
    pass

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

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

(Notez que la page doit être définie avant l'utilisateur. Si je manque un moyen Pythonic pour gérer les dépendances circulaires, laissez-moi savoir.) Chaque document peut être créé et enregistré très bien, mais l'attribution d'une page à un utilisateur renvoie une erreur .

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"

Quelqu'un peut-il expliquer pourquoi cette exception est levée, ce que je fais mal, et comment je peux l'éviter?

Était-ce utile?

La solution

Ceci est la solution appropriée:

from mongoengine import *

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

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

Utilisez des guillemets simples ( 'page') pour désigner les classes qui ne sont pas encore définis.

Autres conseils

La réponse de Drew est la meilleure façon dans ce cas, mais je voulais mentionner que vous pouvez également utiliser un GenereicReferenceField:

from mongoengine import *

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

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

Mais encore une fois, pour votre problème spécifique, rendez-vous avec le nom de classe dans des guillemets simples.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top