这是一个简单的场景:我有一篇附有评论的博文。现在我想使用 mongoforms 让用户提交他们的评论。因此我有这个 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在 forms.py 中支持类似的 ModelForm 功能:
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())
然后,一旦我点击提交按钮,就会出现错误消息:
instance must be a mongoengine document, not BaseList
所以问题是:
- 如何在 MongoEngine 中将 BaseList 转换为 Document?我在没有任何提示的情况下浏览了文档。
- 处理 EmbeddedDocument 的一般最佳做法是什么? ReferenceDocument 有帮助吗?
这里还有一个相关的问题,但没有答案: What is the proper way to update a listfield of embedded documents in mongoengine?
最佳答案
由于嵌入了评论,您需要在帖子对象中查找并更新现有评论。然后您可以用新评论覆盖旧评论(其中 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())
关于python - 将表单保存/更新到 EmbeddedDocument,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9076746/