Pregunta

Estoy construyendo una aplicación Django que utiliza MongoDB y MongoEngine para almacenar datos. Para presentar una versión simplificada de mi problema, digamos que quiere tener dos clases: de usuario y Página. Cada página debe asociarse a un usuario y cada usuario una página.

from mongoengine import *

class Page(Document):
    pass

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

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

(Nota esa página debe definirse antes de usuario. Si me falta una manera Pythonic para manejar dependencias circulares, que me haga saber.) Cada documento puede ser creado y guardado muy bien, pero la asignación de una página a un usuario genera un 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"

Puede alguien explicar por qué esta excepción se está lanzando, lo que estoy haciendo mal, y cómo puedo evitarlo?

¿Fue útil?

Solución

Esta es la solución adecuada:

from mongoengine import *

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

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

Use comillas simples ( 'Página') para indicar las clases que aún no han sido definidos.

Otros consejos

La respuesta de Drew es la mejor manera en este caso, pero quería mencionar que también se puede utilizar un GenereicReferenceField:

from mongoengine import *

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

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

Pero, de nuevo, para su problema específico, ir con el nombre de clase entre comillas simples.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top