save()
:
- 可以与模型对象一起使用,但不能与
QuerySet
或Manager
对象一起使用。
- 使用
select_for_update()
可以运行SELECT FOR UPDATE
查询。
update()
- 可以与
QuerySet
或Manager
对象一起使用,但不能与模型对象一起使用。
- 使用
select_for_update()
无法运行SELECT FOR UPDATE
查询。
例如,我有如下所示的Person
模型:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
然后,您可以使用下面所示的Person
模型对象来调用save()
:
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects.get(id=1)
person.name = 'Tom'
person.save()
return HttpResponse("Test")
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects.filter(pk=1).first()
person.name = 'Tom'
person.save()
return HttpResponse("Test")
但是,您不能像下面示例所示那样在
QuerySet
对象上使用
save()
:
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects.filter(pk=1)
person.name = 'Tom'
person.save()
return HttpResponse("Test")
然后,出现以下错误:
AttributeError:'QuerySet'对象没有属性'save'
并且,您无法像下面所示使用
Manager
对象的
save()
函数:
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects
person.name = 'Tom'
person.save()
return HttpResponse("Test")
然后,会出现以下错误:
AttributeError: 'Manager'对象没有'save'属性
接下来,您可以使用如下所示的QuerySet
对象的update()
方法:
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects.filter(pk=1)
person.update(name="Tom")
return HttpResponse("Test")
而且,您可以像下面展示的那样使用Manager
对象来使用update()
:
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects
person.update(name="Tom")
return HttpResponse("Test")
但是,您不能像下面展示的那样,使用Person
模型对象来使用update()
:
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects.get(id=1)
person.update(name="Tom")
return HttpResponse("Test")
from .models import Person
from django.http import HttpResponse
def test(request):
person = Person.objects.filter(pk=1).first()
person.update(name="Tom")
return HttpResponse("Test")
然后,出现以下错误:
AttributeError: 'Person'对象没有属性'update'
例如,当在Django中更新数据时,使用select_for_update()
可以防止竞争条件(丢失更新或写入偏斜)。
我有一个名为test
视图,其中包含以下内容:save()
和select_for_update().filter(pk=1).first()
:
from django.db import transaction
from .models import Person
from django.http import HttpResponse
@transaction.atomic
def test(request):
person = Person.objects.select_for_update().filter(pk=1).first()
person.name = 'Tom'
person.save()
return HttpResponse("Test")
然后,当我运行test
view时,SELECT FOR UPDATE
和UPDATE
查询如下所示运行。*我使用的是PostgreSQL,下面的日志是PostgreSQL的查询日志,您可以查看{{link1:在PostgreSQL上如何记录带有事务查询的SQL查询,例如“BEGIN”和“COMMIT”}}:
![enter image description here](https://istack.dev59.com/zbXqw.webp)
现在,我删除了 first()
并使用下面的 update()
:
from django.db import transaction
from .models import Person
from django.http import HttpResponse
@transaction.atomic
def test(request):
person = Person.objects.select_for_update().filter(pk=1)
person.update(name="Tom")
return HttpResponse("Test")
然后,当我运行test
view时,SELECT FOR UPDATE
查询没有被运行,只有如下所示的UPDATE
查询被运行:
![enter image description here](https://istack.dev59.com/oirUl.webp)
我有一个带有save()
和select_for_update().get(pk=1)
的test
视图,如下所示:
from django.db import transaction
from .models import Person
from django.http import HttpResponse
@transaction.atomic
def test(request):
person = Person.objects.select_for_update().get(pk=1)
person.name = 'Tom'
person.save()
return HttpResponse("Test")
然后,当我运行test
view时,SELECT FOR UPDATE
和UPDATE
查询如下所示:
![enter image description here](https://istack.dev59.com/y6oFQ.webp)
现在,我将
get()
替换为下面所示的
update()
。
from django.db import transaction
from .models import Person
from django.http import HttpResponse
@transaction.atomic
def test(request):
person = Person.objects.select_for_update()
person.update(name="Tom")
return HttpResponse("Test")
然后,当我运行测试
视图时,SELECT FOR UPDATE
查询并没有运行,只有UPDATE
查询被执行,如下所示:
![enter image description here](https://istack.dev59.com/EVmDA.webp)
那么,
save()
与
select_for_update()
可以运行
SELECT FOR UPDATE
查询,而
update()
与
select_for_update()
则不能。
AttributeError: 'TableName' object has no attribute 'update'
。filter
似乎可以工作,但是get
不行。 - Srinath Ganesh.update()
方法仅适用于QuerySet,该QuerySet是.filter()
方法的结果。如果使用.get()
,则只会获得单个对象,并且需要使用.save()
。 - zoidberg