Внедрение двунаправленных отношений в MongoEngine - PullRequest
21 голосов
/ 08 октября 2010

Я создаю приложение Django, которое использует MongoDB и MongoEngine для хранения данных. Чтобы представить упрощенную версию моей проблемы, скажем, я хочу иметь два класса: Пользователь и Страница. Каждая страница должна ассоциироваться с пользователем, а у каждого пользователя - страница.

from mongoengine import *

class Page(Document):
    pass

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

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

(Обратите внимание, что страница должна быть определена до пользователя. Если мне не хватает Pythonic для обработки циклических зависимостей, дайте мне знать.) Каждый документ может быть создан и сохранен просто отлично, но назначение страницы пользователю выдает ошибку .

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"

Может кто-нибудь объяснить, почему выбрасывается это исключение, что я делаю неправильно и как мне этого избежать?

Ответы [ 2 ]

39 голосов
/ 09 октября 2010

Это правильное решение:

from mongoengine import *

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

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

Используйте одинарные кавычки ('Page') для обозначения классов, которые еще не определены.

10 голосов
/ 15 апреля 2011

Ответ Дрю - лучший способ в этом случае, но я хотел отметить, что вы также можете использовать GenereicReferenceField:

from mongoengine import *

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

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

Но опять же, для вашей конкретной проблемы, используйте имя класса в одинарных кавычках.

...