Django更新对象

Joh*_*ohn 114 sql django orm django-models django-queryset

如何在同一个查询集上运行update和select语句,而不是必须执行两个查询,一个用于选择对象,另一个用于更新对象?

SQL中的等价物如下:

update my_table set field_1 = 'some value' where pk_field = some_value
Run Code Online (Sandbox Code Playgroud)

Dan*_*man 218

使用queryset 对象update方法:

MyModel.objects.filter(pk=some_value).update(field1='some value')
Run Code Online (Sandbox Code Playgroud)

  • 只是一个公平的警告...如果您使用这样的`update`方法,那么附加到该模型或其他"代码内容"的任何信号都不会针对这些对象运行.只是一个被烧伤的人的指针:) (82认同)
  • @DipakChandranP你应该问一个新问题而不是对一个六岁的问题发表评论.但是F()表达式可能是你想要的. (8认同)
  • @学习得好伙计,这完全取决于你的情况。“update”方法非常适合批量更新,但是当您使用它时,它应该在您的脑海中发出警告,您需要检查附加到该对象的任何信号,这些信号可能还需要手动触发 (5认同)
  • @DMctheDestroyer 9年后,我终于明白了你的评论。/sf/answers/5018195521/ (5认同)
  • 是否可以在更新功能中访问当前模型实例?比如`MyModel.objects.filter(pk = some_value).update(field1 = self.data) (3认同)

Sli*_*eam 55

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

obj = Product.objects.get(pk=pk)
obj.name = "some_new_value"
obj.save()
Run Code Online (Sandbox Code Playgroud)

Django如何知道UPDATE与INSERT
如果对象的主键属性设置为一个值为True的值(即,None或空字符串以外的值),Django将执行UPDATE.如果未设置对象的主键属性或者UPDATE没有更新任何内容,Django将执行INSERT.

参考:https://docs.djangoproject.com/en/1.9/ref/models/instances/


Pra*_*ari 13

这个答案比较了以上两种方法。如果要在一行中更新许多对象,请执行以下操作:

# Approach 1
MyModel.objects.filter(field1='Computer').update(field2='cool')
Run Code Online (Sandbox Code Playgroud)

否则,您将不得不遍历查询集并更新单个对象:

#Approach 2    
objects = MyModel.objects.filter(field1='Computer')
for obj in objects:
    obj.field2 = 'cool'
    obj.save()
Run Code Online (Sandbox Code Playgroud)
  1. 方法1更快,因为与方法2进行“ n + 1”个数据库查询相比,它仅进行一个数据库查询。(对于查询集中的n个项目)

  2. 第一种方法进行一个数据库查询,即UPDATE,第二种方法进行两个查询:SELECT然后是UPDATE。

  3. 代价是,假设您有任何触发器,例如更新updated_on或任何此类相关字段,则不会在直接更新(即方法1)上被触发。

  4. 方法1用于查询集,因此可以一次更新多个对象,而不是方法2。


Rom*_*val 6

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

update my_table set field_1 = field_1 + 1 where pk_field = some_value
Run Code Online (Sandbox Code Playgroud)

使用查询表达式

MyModel.objects.filter(pk=some_value).update(field1=F('field1') + 1)
Run Code Online (Sandbox Code Playgroud)

这将以原子方式执行更新,即使用对数据库的一个更新请求,而不先读取它。


Riy*_* Ac 6

第一种方法

MyTable.objects.filter(pk=some_value).update(field1='some value')
Run Code Online (Sandbox Code Playgroud)

方法二

q = MyModel.objects.get(pk=some_value)
q.field1 = 'some value'
q.save()
Run Code Online (Sandbox Code Playgroud)

第三种方法

通过使用 get_object_or_404

q = get_object_or_404(MyModel,pk=some_value)
q.field1 = 'some value'
q.save()
Run Code Online (Sandbox Code Playgroud)

第四种方法

如果你需要,如果pk=some_value存在,那么update它的其他明智create使用新的update_or_create

MyModel.objects.update_or_create(pk=some_value,defaults={'field1':'some value'})
Run Code Online (Sandbox Code Playgroud)