如何在Django中使用"select_for_update()"获取对象?

44
根据Django文档所述,select_for_update返回一个Queryset,但是get不是这样。现在我有一个查询,我确定它只会返回一个元组。但是我还需要为此事务获取锁定。因此,我正在执行以下操作:
ob = MyModel.objects.select_for_update().filter(some conditions)
现在,我需要修改一些ob的值。但是ob是一个Queryset。这似乎很简单,但是我还不太熟悉Django。请给些建议。
3个回答

61

只需调用get、切片等操作,然后像往常一样保存即可。锁定已通过事务实现。

ob = MyModel.objects.select_for_update().get(pk=1)
任何更改都会在事务结束时提交(默认情况下,通过1.5是每个请求)。

那么,我可以直接在 get 上使用 select_for_update(),而不是进行过滤操作吗? - Indradhanush Gupta
@IndradhanushGupta 不,顺序不正确。你在 select_for_update() 上使用 get,因为 get 返回一个对象,而不是 QuerySet。 - minmaxavg
1
请澄清一下,我没有理解你上一句话中的“1.5 thingie”。 - Mohammed Shareef C
1.5 指的是 Django 的版本。默认情况下,锁定将一直持续到请求结束。 - NFern

46
你也可以在编程中使用 select_for_updateget_object_or_404 函数:

可以参考这个链接。

from django.db import transaction
from django.shortcuts import get_object_or_404

with transaction.atomic():
    obj = get_object_or_404(MyModel.objects.select_for_update(), pk=pk)
    # do some stuff with locked obj

1
select_for_update().filter() 之后,您可以放置 .first(),它将返回一个 queryset 的第一个对象,以便使用 save() 更新它,如下所示。*您可以查看 我的问题和答案,了解有关 Django 中 select_for_update() 的更多信息:
                                                                # Here
ob = MyModel.objects.select_for_update().filter(some conditions).first()
ob.field_1 = 'some value'
ob.save()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接