3

我有一个嵌入式文档类Post和一个父类Thread

class Thread(Document):
    ...
    posts = ListField(EmbeddedDocumentField("Post"))

class Post(EmbeddedDocument): 
    attribute = StringField()
    ...

我想创建一个新帖子并将其添加到我ListFieldThread课堂上。

我的代码如下所示:

post = Post()
post.attribute = "noodle"
post.save()
thread.posts.append(post)
thread.save()

但我收到以下错误消息:

“‘发布’对象没有属性‘保存’”

如果我跳过post.save()一个空Post对象附加到我的Thread.

有任何想法吗?

4

2 回答 2

7

嵌入文档不作为单独的、独立于其文档实例的实例存在,即要保存嵌入文档,您必须将文档本身保存在嵌入的位置;另一种看待它的方式是,您不能在没有实际文档的情况下存储嵌入式文档。

这也是原因,虽然您可以过滤包含特定嵌入文档的文档,但您不会收到匹配的嵌入文档本身——您将收到它所属的整个文档。

thread = Thread.objects.first()  # Get the thread
post = Post()
post.attribute = "noodle"
thread.posts.append(post)  # Append the post
thread.save()  # The post is now stored as a part of the thread
于 2012-08-06T09:23:23.420 回答
5

您的代码看起来不错 - 您确定没有其他线程对象吗?这是一个证明您的代码的测试用例(没有 post.save() 步骤)。你安装的是什么版本?

import unittest
from mongoengine import *


class Test(unittest.TestCase):

    def setUp(self):
        conn = connect(db='mongoenginetest')

    def test_something(self):

        class Thread(Document):
            posts = ListField(EmbeddedDocumentField("Post"))

        class Post(EmbeddedDocument):
            attribute = StringField()

        Thread.drop_collection()

        thread = Thread()
        post = Post()
        post.attribute = "Hello"

        thread.posts.append(post)
        thread.save()

        thread = Thread.objects.first()
        self.assertEqual(1, len(thread.posts))
        self.assertEqual("Hello", thread.posts[0].attribute)
于 2012-08-06T10:14:23.173 回答