Python 将查询集作为参数传递给django中的_?
我有一个从模型方法中的查询中获得的对象ID列表,然后我使用该列表从不同的模型中删除对象:Python 将查询集作为参数传递给django中的_?,python,django,django-orm,Python,Django,Django Orm,我有一个从模型方法中的查询中获得的对象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
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\u或\u create()
,需要3个查询,但在真正的代码中,它实际上是.filter(some\u param=some\u param)。first()
而不是.get()
,所以我认为没有任何简单的方法可以解决这个问题)
如何将未计算的查询集作为参数传递给查找中的\u
我想做一些类似的事情:
ids_to_delete = self.items.all().values("id")
other_object.items.filter(item_id__in=ids_to_delete).delete()
您可以将QuerySet
传递给查询:
other_object.items.filter(id__in=self.items.all()).delete()
other\u object.items.filter(id\u in=self.items.all()).delete()
这将在子查询中转换它。但并非所有数据库,尤其是MySQL数据库,都能很好地处理此类子查询。此外,Django手动处理.delete()
。因此,它将进行查询以获取项目的主键,然后触发删除逻辑(并删除具有级联
依赖关系的项目)。因此,.delete()
不是作为一个查询完成的,而是至少两个查询,而且通常由于带有on\u delete
触发器的ForeignKey
s而导致更大的查询量
但是请注意,此处删除的是项
对象,而不是从其他对象
中“取消链接”。因为这是可以使用的。我应该尝试我发布的代码示例,事实上你可以这样做。它与中的任何示例一样给出,但它说“小心使用嵌套查询并了解数据库服务器的性能特征”,建议不要这样做,将子查询强制转换到列表中:
values = Blog.objects.filter(
name__contains='Cheddar').values_list('pk', flat=True)
entries = Entry.objects.filter(blog__in=list(values))
你能分享其他对象
和项目
的模型吗?@WillemVanOnsem我认为这不会帮助你回答我的问题,这是一个关于如何在
中为\u使用未评估的查询集的一般性问题。这里,.delete()
将删除项目
而不是它与这些项目的关系(因此.remove()
)。这可能不是预期的效果,因为您可以使用self.items.all().delete()完成此操作
例如,这要视情况而定:强制转换到列表有时可以显著提高整体性能,即使它会执行额外的查询。我看到使用复杂子查询时,查询的执行速度会慢三个数量级。通常,我作为子查询离开,如果我注意到性能问题,我会转换为列表(并说明原因)。