19

我正在构建一个使用MongoDB和MongoEngine存储数据的Django应用程序。为了呈现我的问题的简化版本,假设我想要两个类:用户和页面。每个页面应该与一个用户和每个用户关联一个页面。在MongoEngine中实现双向关系

from mongoengine import * 

class Page(Document): 
    pass 

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

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

(请注意,页面必须用户之前定义。如果我缺少一个Python化的方式来处理循环依赖,让我知道。)每个文件可以创建并保存得很好,但到指定页面用户引发错误。

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" 

任何人都可以解释为什么这个异常被抛出,我做错了什么,我怎么能避免它?

+0

我能看到的一个错误是,您已经定义了一个名为author的字段并设置了一个名为user的字段。 发布的代码是你实际运行的吗? – Ian 2010-10-07 21:17:16

+0

是的,但不幸的是,这不是我的问题的根源。犯这个错误只会给我的对象添加一个变量,但不会影响MongoEngine save()函数。 – 2010-10-08 20:03:11

回答

33

这是妥善的解决办法:

from mongoengine import * 

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

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

使用单引号(“页”)来表示还没有被定义的类。

8

德鲁的答案是在这种情况下,最好的办法,但我想提一提,你也可以使用一个GenereicReferenceField:再次

from mongoengine import * 

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

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

但是,对于您的具体问题,请在单引号类名。