【问题标题】:Delete multiple Django objects via ORM通过 ORM 删除多个 Django 对象
【发布时间】:2020-02-13 04:26:04
【问题描述】:

是否可以删除许多 Model 实例而不对其进行迭代并在每个实例上调用 .delete()?

假设我们有这样的东西:

objects = [o for o in MyObject.objects.filter(...)]

objects_to_delete = get_validate_objects(objects) # some of objects from objects

现在我想删除objects_to_delete 中的每个MyObject。 还有比这更好/更聪明的方法吗?:

for o in objects_to_delete:
    o.delete()

我还想确保所有对象都已删除。 删除对象(之前已删除)期间有关问题的异常/消息会很好。

【问题讨论】:

  • 你可以自定义你的 Manager 类,这样MyObject.valid_objects 已经返回了一个带有自定义过滤器语义的过滤器集,然后只是objects.delete() 他们
  • 我重新打开了这个,因为链接的问题略有不同,单一答案没有回答这个问题。

标签: python django


【解决方案1】:

你可以删除一个查询集;要获取包含您在列表中的对象的查询集,您可以这样做:

objects_to_delete = MyObject.objects.filter(pk__in=[o.pk for o in objects])
objects_to_delete.delete()

但理想情况下,您应该以这样一种方式编写“get_validate_objects”:它将查询集作为参数并对查询集进行所有检查(使用 filter() 和 exclude() 等)。然后你可以立即对结果调用 .delete() 。但这当然并不总是那么容易。

【讨论】:

  • 我明白了。但它没有解决pk__in 中的对象早先被删除的问题。没有消息或异常。我只能将已删除 ID 列表与已删除对象数进行比较。
  • @kedod:这是一个更根本的问题,如果您使用带有 IN 子句的 DELETE SQL 语句,其中并非所有 id 都与表中的某些行匹配,数据库软件不会给您错误.所以你不会从中得到错误,就关系数据库而言是可以的。
  • 另外,你在做什么使得它们可能已经被删除了,如果它们已经被删除又有什么关系?
【解决方案2】:

由于您在objects_to_delete 中有对象,因此您可以获取这些对象的ID 并删除。执行以下操作:

MyObject.objects.filter(id__in=[i.id for i in objects_to_delete]).delete()

会产生如下的SQL。

DELETE FROM MyObject WHERE id IN (ids of objects)

例如如果要删除的对象的 id 是 1,2,3,4,5 那么 sql 将是:

DELETE FROM MyObject WHERE id IN (1, 2, 3, 4, 5)

【讨论】:

  • 我明白了。但它没有解决之前删除pk__in 中的对象的问题。没有消息或异常。我只能将已删除的 id 列表与已删除对象的数量进行比较。
猜你喜欢
  • 2016-09-05
  • 2019-01-05
  • 2020-08-04
  • 1970-01-01
  • 2013-05-19
  • 2020-01-31
  • 1970-01-01
  • 2012-02-26
  • 2014-05-27
相关资源
最近更新 更多