I am trying to define methods for performing checks and updates to a listfield of embedded documents in mongoengine. W开发者_开发问答hat is the proper way of doing what I'm trying to do. The code is below.
class Comment(EmbeddedDocument):
created = DateTimeField()
text = StringField()
class Post(Document):
comments = ListField(EmbeddedDocumentField(Comment))
def check_comment(self, comment):
for existing_comment in self.comments:
if comment.created == existing_comment.created and
comment.text == existing_comment.text:
return True
return False
def add_or_replace_comment(self, comment):
for existing_comment in self.comments:
if comment.created == existing_comment.created:
# how do I replace?
# how do I add?
Is this even the correct way to go about something like this?
You need to find the index of the existing comment.
You can then overwrite the old comment with the new comment (where i is the index) eg:
post.comments[i] = new_comment
then just do a post.save()
and mongoengine will convert that to a $set
operation.
Alternatively, you could just write the $set
eg:
Post.objects(pk=post.pk).update(set__comments__i=comment)
You could use an EmbeddedDocumentListField instead of a list of embedded documents. That way you get access to some handy methods like filter, create or update:
class Comment(EmbeddedDocument):
created = DateTimeField()
text = StringField()
class Post(Document):
comments = EmbeddedDocumentListField(Comment)
...
def add_or_replace_comment(self, comment):
existing = self.comments.filter(created=comment.created)
if existing.count() == 0:
self.comments.create(comment)
else:
existing.update(comment)
(code not tested)
精彩评论