基本上我有邮政凭证和Comment
EmbeddedDocument
,如下:
class Comment(EmbeddedDocument):
value1 = StringField(max_length=200,)
value2 = StringField(max_length=200,)
value3 = StringField(max_length=200,)
id = UUIDField(required=True, primary_key=True)
class Post(Document,):
comments = EmbeddedDocumentListField(Comment, required=False)
PUT
请求可以针对给定帖子的给定评论更新value1,value2和value3的任意组合。我使用queryset update
方法执行以下操作:
post = Post.objects.get(id=post_id)
comment = None
for comm in post.comments:
if comm.id == comment_id:
comment = comm
Post.objects(
id=post_id,
comments__id=comment_id
).update(
set__comments__S__value1=new_value1 or comment.value1,
set__comments__S__value2=new_value2 or comment.value2,
set__comments__S__value3=new_value3 or comment.value3,
)
但是这显然不是Read–modify–write原子操作。如此热烈的读取-修改-写入是一项原子操作?
位置运算符允许您在不知道索引位置的情况下更新列表项,因此使更新成为单个原子操作。
位置运算符(set__comments__S__value1)允许您更新将由comments__id=comment_id
选择的精确注释。这意味着您无需循环即可获得评论。您只需执行一项操作就可以完成所有操作。
可以使用
update_one()
自动更新文档,update()
或modify()
和QuerySet
上的modify()
和save()
方法(带有save_condition参数)在Document
上。
详细here
用给定ID仅更新一个Comment
的代码:
def put(value1=None, value2=None, value3=None):
data = {}
if value1:
data['set__comments__S__value1'] = value1
if value2:
data['set__comments__S__value2'] = value2
if value3:
data['set__comments__S__value3'] = value2
Post.objects(
id='5dab09cade20c4423a9cb4d1',
comments__id='18f75928-36d5-415d-b8a9-18488f954e68'
).update(**data)