Сохранить / обновить форму в EmbeddedDocument - PullRequest
2 голосов
/ 31 января 2012

Вот простой сценарий: у меня есть пост в блоге с прикрепленными к нему комментариями.Теперь я хочу использовать 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 для поддержки аналогичной функциональности ModelForm в формах .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. Как преобразовать BaseList в Document в MongoEngine?Я просмотрел документ без подсказки.
  2. Каковы наиболее эффективные методы работы с EmbeddedDocument?Поможет ли ReferenceDocument?

Также здесь есть связанные вопросы, но без ответа: Как правильно обновить поле списка встроенных документов в mongoengine?

1 Ответ

2 голосов
/ 31 января 2012

Поскольку комментарии добавлены, вам необходимо найти и обновить существующий комментарий в объекте post.Затем вы можете перезаписать старый комментарий новым комментарием (где i - индекс), например:

post.comments[i] = new_comment

, затем просто выполните post.save(), и mongoengine преобразует его в $set операция.

В качестве альтернативы, вы можете просто написать $set напрямую, например:

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

Forms.py

Я все еще используюформ.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())
...