开发者

Implementing Bi-Directional relationships in MongoEngine

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜