I'm building a Django application that uses MongoDB and MongoEngine to store data. To present a simplified version of my problem, say I want to have two classes: User and Page. Each page should associate itself with a user and each user a page.
from mongoengine import *
class Page(Document):
pass
class User(Document):
name = StringField()
page = ReferenceField(Page)
class Page(Document):
content = StringField()
user = ReferenceField(User)
(Note that Page must be defined before User. If I am missing a Pythonic way to handle circular dependencies, let me know.) Each document can be created and saved just fine, but assigning a Page to a User throws an error.
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"
Can anyone expla开发者_运维百科in why this exception is being thrown, what I am doing wrong, and how I can avoid it?
This is the proper solution:
from mongoengine import *
class User(Document):
name = StringField()
page = ReferenceField('Page')
class Page(Document):
content = StringField()
user = ReferenceField(User)
Use single quotes ('Page') to denote classes that have not yet been defined.
Drew's answer is the best way in this case, but I wanted to mention that you can also use a GenereicReferenceField:
from mongoengine import *
class User(Document):
name = StringField()
page = GenericReferenceField()
class Page(Document):
content = StringField()
user = ReferenceField(User)
But again, for your specific problem, go with the class name in single quotes.
精彩评论