Guardar / actualizar un formulario a un documento incrustado

Here is a simple scenario: I have a blog post with comments attach to it. Now I want to use mongoforms to let user submit their comments. Therefore I have this modelos.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)

Y estoy usando django-mongoforms to support the similar ModelForm functionality, within formularios.py:

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

En los views.py, I just want to save what user has entered, more specifically the Author and Body fields of a comment, here is the method to add a comment:

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())

Then once I click Submit button here comes the error message:

instance must be a mongoengine document, not BaseList

Así que las preguntas son:

  1. How to covert BaseList to Document in MongoEngine? I have looked through the document without a hint.
  2. What's the best practices here generally to handle the EmbeddedDocument? Will ReferenceDocument help?

Also there is a related questions here but without an answer: ¿Cuál es la forma correcta de actualizar un campo de lista de documentos incrustados en mongoengine?

preguntado el 31 de enero de 12 a las 08:01

1 Respuestas

As comments are embedded you'll need to find and update the existing comment in the post object. You can then overwrite the old comment with the new comment (where i es el índice) por ejemplo:

post.comments[i] = new_comment

entonces solo haz un post.save() y mongoengine lo convertirá en un $set operación.

Alternativamente, puede escribir el $set directly eg:

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

Forms.py

I still use the forms.py but I would pass commit=False a save that will return the comment - then append to the post and save the post like so:

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())

Respondido el 31 de enero de 12 a las 18:01

That worked! Thank you for the warm help on both freenode and here all the way long. - Liki

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.