【问题标题】:Save/update a form to an EmbeddedDocument将表单保存/更新到 EmbeddedDocument
【发布时间】:2012-01-31 08:49:50
【问题描述】:

这是一个简单的场景:我有一篇附有 cmets 的博客文章。现在我想使用 mongoforms 让用户提交他们的 cmets。因此我有这个 models.py:

class Post(Document):
    title = StringField(max_length=60)
    body = StringField()
    created = DateTimeField(default=datetime.datetime.now)
    comments = ListField(EmbeddedDocumentField('Comment'))

class Comment(EmbeddedDocument):
    author = StringField(max_length=60)
    body = StringField()
    created = DateTimeField(default=datetime.datetime.now)

我正在使用django-mongoforms 来支持类似的 ModelForm 功能,在 forms.py 中:

class CommentForm(MongoForm):
    class Meta:
        document = Comment
        fields = ('author', 'body')

在views.py中,我只想保存用户输入的内容,更具体地说是评论的作者和正文字段,这里是添加评论的方法:

def add_comment(request, id):
    post = Post.objects.with_id(id)
    if request.method == 'POST':
        form = CommentForm(request.POST, instance=post.comments)
        if form.is_valid():
            form.save()
    return HttpResponseRedirect(post.get_absolute_url())

然后,一旦我点击提交按钮,就会出现错误消息:

实例必须是 mongoengine 文档,而不是 BaseList

所以问题是:

  1. 如何在 MongoEngine 中将 BaseList 转换为 Document?我在没有任何提示的情况下浏览了文档。
  2. 这里处理 EmbeddedDocument 的最佳实践是什么? ReferenceDocument 会有帮助吗?

这里还有一个相关的问题,但没有答案: What is the proper way to update a listfield of embedded documents in mongoengine?

【问题讨论】:

    标签: python django mongodb mongoengine


    【解决方案1】:

    由于嵌入了 cmets,您需要在帖子对象中查找并更新现有评论。然后,您可以用新评论(其中 i 是索引)覆盖旧评论,例如:

    post.comments[i] = new_comment
    

    然后只需执行 post.save() 并且 mongoengine 会将其转换为 $set 操作。

    或者,您可以直接写$set 例如:

    Post.objects(pk=post.pk).update(set__comments__i=comment)
    

    Forms.py

    我仍然使用 forms.py,但我会将 commit=False 传递给 save,这将返回评论 - 然后附加到帖子并保存帖子,如下所示:

    def add_comment(request, id):
        post = Post.objects.with_id(id)
        if request.method == 'POST':
            form = CommentForm(request.POST)
            if form.is_valid():
                comment = form.save(commit=False)
                post.comments.append(comment)
                post.save()
        return HttpResponseRedirect(post.get_absolute_url())
    

    【讨论】:

    • 成功了!感谢您一直以来对 freenode 和这里​​的热情帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 2018-06-01
    相关资源
    最近更新 更多