如何在Django中用一个查询集选择一条记录并更新它?

9gm1akwq  于 2023-03-24  发布在  Go
关注(0)|答案(8)|浏览(135)

如何在同一个queryset上运行updateselect语句,而不必执行两个查询:- 一个用于选择对象-一个用于更新对象
在SQL中的等价形式如下:

update my_table set field_1 = 'some value' where pk_field = some_value
3mpgtkmj

3mpgtkmj1#

使用queryset对象update方法:

MyModel.objects.filter(pk=some_value).update(field1='some value')
m1m5dgzv

m1m5dgzv2#

Django数据库对象使用相同的保存()方法来创建和更改对象。

obj = Product.objects.get(pk=pk)
obj.name = "some_new_value"
obj.save()

Django如何知道UPDATE和INSERT

如果对象的主键属性被设置为一个计算结果为True的值(即,一个非None或空字符串的值),Django执行UPDATE。如果对象的主键属性没有被设置或UPDATE没有更新任何内容,Django执行INSERT。
参考编号:https://docs.djangoproject.com/en/1.9/ref/models/instances/

a1o7rhls

a1o7rhls3#

这个答案比较了上述两种方法。如果你想在一行中更新很多对象,可以选择:

# Approach 1
MyModel.objects.filter(field1='Computer').update(field2='cool')

否则,您必须遍历查询集并更新各个对象:

#Approach 2    
objects = MyModel.objects.filter(field1='Computer')
for obj in objects:
    obj.field2 = 'cool'
    obj.save()

1.方法1更快,因为它只进行一个数据库查询,而方法2进行“n+1”个数据库查询。(对于查询集中的n个项目)
1.第一种方法生成一个数据库查询,即UPDATE,第二种方法生成两个:选择,然后更新。
1.折衷的办法是,假设你有任何触发器,比如更新updated_on或任何类似的相关字段,它不会在直接更新ie方法1时被触发。
1.方法1用于查询集,因此可以一次更新多个对象,而不是方法2的情况。

f45qwnt8

f45qwnt84#

第一种方法

MyTable.objects.filter(pk=some_value).update(field1='some value')

第二种方法

q = MyModel.objects.get(pk=some_value)
q.field1 = 'some value'
q.save()

第三种方法

使用get_object_or_404

q = get_object_or_404(MyModel,pk=some_value)
q.field1 = 'some value'
q.save()

第四种方法

如果您需要pk=some_value是否存在,则updatecreate,否则使用update_or_create创建新的create

MyModel.objects.update_or_create(pk=some_value,defaults={'field1':'some value'})
iecba09b

iecba09b5#

如果您需要根据旧字段值设置新值,请执行以下操作:

update my_table set field_1 = field_1 + 1 where pk_field = some_value

使用query expressions

MyModel.objects.filter(pk=some_value).update(field1=F('field1') + 1)

这将原子地执行更新,即使用对数据库的一个更新请求而不首先阅读它。

zpgglvta

zpgglvta6#

只有在serializer的情况下,你可以用很简单的方式更新!

my_model_serializer = MyModelSerializer(
    instance=my_model, data=validated_data)
if my_model_serializer.is_valid():

    my_model_serializer.save()

只在form的情况下的事情!

instance = get_object_or_404(MyModel, id=id)
form = MyForm(request.POST or None, instance=instance)
if form.is_valid():
    form.save()
wljmcqd8

wljmcqd87#

接受的答案效果很好,但它会带来一些不必要的副作用。
例如,您正在使用imageField,update()将工作并更新其他数据,但不更新您的imageField数据

class ProfileSetting(models.Model):

    first_name = models.CharField(blank=True)

    logo = models.ImageField(blank=True, null=True, upload_to="profile/logo/")
update_data = {
  "first_name": "john",
  "logo": request.FILES['logo'] # logo will not be properly update
}

ProfileSetting.objects.filter(pk=some_value).update(**update_data)

下面是一些示例,其中有很好的解释Django ImageField is not updating when update() method is used

brjng4g3

brjng4g38#

上面提到的答案工作得很好,但它会产生一些不必要的副作用,因此为了避免此类错误,请将数据库代码写入异常块中。

try:
        obj = <Your_Model_Name>.objects.get(PK=<pk_id>)
        obj.name = req.POST.get("name")
        obj.save()
    except Exception as e:
        print(e)

相关问题