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

发布于 2024-08-30 06:04:57 字数 233 浏览 7 评论 0原文

如何在同一个 queryset 上运行 updateselect 语句,而不必执行两个查询: - 一项选择对象 - 以及更新对象

SQL 中的等效项类似于:

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

How do I run an update and select statements on the same queryset rather than having to do two queries:
- one to select the object
- and one to update the object

The equivalent in SQL would be something like:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

分開簡單 2024-09-06 06:04:57

使用查询集对象更新方法

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

Use the queryset object update method:

MyModel.objects.filter(pk=some_value).update(field1='some value')
悸初 2024-09-06 06:04:57

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

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

Django 如何知道更新与插入
如果对象的主键属性设置为计算结果为 True 的值(即,一个值
除了 None 或空字符串),Django 执行更新。如果
对象的主键属性未设置或者 UPDATE 未设置
更新任何内容,Django 都会执行 INSERT。

参考: https://docs.djangoproject.com/en/5.0/参考/模型/实例/

Django database objects use the same save() method for creating and changing objects.

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

How Django knows to UPDATE vs. INSERT
If the object’s primary key attribute is set to a value that evaluates to True (i.e., a value
other than None or the empty string), Django executes an UPDATE. If
the object’s primary key attribute is not set or if the UPDATE didn’t
update anything, Django executes an INSERT.

Ref.: https://docs.djangoproject.com/en/5.0/ref/models/instances/

做个ˇ局外人 2024-09-06 06:04:57

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

# 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 个项目)

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

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

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

This answer compares the above two approaches.
If you want to update many objects in a single line, go for:

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

Otherwise you would have to iterate over the query set and update individual objects:

#Approach 2    
objects = MyModel.objects.filter(field1='Computer')
for obj in objects:
    obj.field2 = 'cool'
    obj.save()
  1. Approach 1 is faster because, it makes only one database query, compared to approach 2 which makes 'n+1' database queries. (For n items in the query set)

  2. Fist approach makes one db query ie UPDATE, the second one makes two: SELECT and then UPDATE.

  3. The tradeoff is that, suppose you have any triggers, like updating updated_on or any such related fields, it will not be triggered on direct update ie approach 1.

  4. Approach 1 is used on a queryset, so it is possible to update multiple objects at once, not in the case of approach 2.

飘然心甜 2024-09-06 06:04:57

第一种方法

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 存在,然后更新它,否则使用update_or_create创建新值。

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

1st method

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

2nd Method

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

3rd method

By using get_object_or_404

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

4th Method

if you required if pk=some_value exist then update it other wise create new one by using update_or_create.

MyModel.objects.update_or_create(pk=some_value,defaults={'field1':'some value'})
银河中√捞星星 2024-09-06 06:04:57

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

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

使用 查询表达式

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

这将自动执行更新,即使用对数据库的一个更新请求,而不先读取它。

If you need to set the new value based on the old field value that is do something like:

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

use query expressions:

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

This will execute update atomically that is using one update request to the database without reading it first.

隐诗 2024-09-06 06:04:57

仅在 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()

only in a case in serializer things, you can update in very simple way!

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

    my_model_serializer.save()

only in a case in form things!

instance = get_object_or_404(MyModel, id=id)
form = MyForm(request.POST or None, instance=instance)
if form.is_valid():
    form.save()
溺孤伤于心 2024-09-06 06:04:57

接受的答案效果很好,但它带来了一些不需要的副作用。

例如,您正在使用 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)

这是一些带有很好解释的示例 使用 update() 方法时 Django ImageField 不更新

Accepted answer works great, but it comes with some unwanted side effect.

For example, you are using imageField, the update() will work and update others data, but not update your imageField data

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)

Here is some example with good explanation Django ImageField is not updating when update() method is used

茶底世界 2024-09-06 06:04:57

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

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

Above mentioned answer works great, but it happens with some unwanted side effect, so to avoid such errors writes your db code inside exception blocks.

    try:
        obj = <Your_Model_Name>.objects.get(PK=<pk_id>)
        obj.name = req.POST.get("name")
        obj.save()
    except Exception as e:
        print(e)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文