我有一个对象ID列表,它是从一个模型的方法中的查询中获得的,然后我使用该列表从另一个模型中删除对象:
class SomeObject(models.Model):
# [...]
def do_stuff(self, some_param):
# [...]
ids_to_delete = {item.id for item in self.items.all()}
other_object = OtherObject.objects.get_or_create(some_param=some_param)
other_object.items.filter(item_id__in=ids_to_delete).delete()
我不喜欢的是,这需要2个查询(从技术上讲,get_or_create()
需要3个查询,但在实际代码中,它实际上是.filter(some_param=some_param).first()
而不是.get()
,所以我不认为有任何简单的方法可以解决这个问题)。
如何将未计算的queryset作为参数传递给__in
查找?
我想这样做:
ids_to_delete = self.items.all().values("id")
other_object.items.filter(item_id__in=ids_to_delete).delete()
2条答案
按热度按时间u5rb5r591#
您可以将
QuerySet
传递给查询:这将把它转换成一个子查询。但不是所有的数据库,特别是MySQL数据库,都能很好地处理这样的子查询。此外,Django * 手动 * 处理
.delete()
。它将因此进行一个查询来获取条目的主键,然后触发删除逻辑因此.delete()
不是作为一个查询完成的,而是作为至少两个查询完成的,并且由于X1 M5 N1 X触发器的X1 M4 N1 X而通常具有更大的量。但是请注意,您在这里 * 移除 *
Item
对象,而不是从other_object
中“取消链接”。为此,可以使用**.remove(…)
**[Django-doc]。neskvpey2#
我应该尝试一下我发布的代码示例,实际上你可以做到这一点。文档中给出了一个示例,但它说“小心使用嵌套查询并了解数据库服务器的性能特征”,并建议不要这样做,将子查询转换为列表: