重复的django查询集?
我有一个简单的 Django 查询集,像这样:
qs = AModel.objects.exclude(state="F").order_by("order")
我想这样使用它:
qs[0:3].update(state='F')
expected = qs[3] # throws error here
但是最后这条语句报错了:
"一旦进行了切片,就无法更新查询。"我该如何复制这个查询集呢?
3 个回答
0
之前有一些讨论,想要实现对查询集(queryset)进行切片,然后在这些切片上使用更新操作,但据我所知,这方面并没有实际的成果。我觉得你不能直接复制一个查询集的切片,但在这种情况下你其实不需要这样做。如果你的顺序是一个唯一的整数,你可以这样做:
qs = AModel.objects.exclude(state="F").order_by("order")
if len(qs) > 3:
slice = qs.exclude(order__gt=qs[3])
else:
slice = qs
slice.update(state='F')
我使用exclude来去掉不需要的元素,但这只有在顺序是唯一的情况下才有效,否则你就无法知道你更新了多少个。如果顺序不是唯一的,仍然可以通过在顺序中使用第二个唯一的参数来实现:
qs = AModel.objects.exclude(state="F").order_by("order", "pk")
if len(qs) > 3:
slice = qs.exclude(order__gt=qs[3]).exclude(order=qs[3], pk__gt=qs[3])
...
1
你可以这样做:
qs = AModel.objects.filter(id__in= AModel.objects.exclude(state="F").order_by("order")[10]).update()
2
错误是出在第一行:你不能这样用 qs[0:3].update()。qs[0:3] 是在取一个切片;而 update() 是用来更新查询的。
update() 是用来批量更新的,生成的 SQL 查询看起来像这样:
UPDATE app_model SET state = 'F' WHERE state <> 'F';
你想根据“order”来更新前三个项目,但这种 UPDATE 是做不到的——在 SQL 的 UPDATE 中,你不能排序或限制更新的数量。需要用不同的方式来写,比如:
UPDATE app_model SET state = 'F' WHERE id IN (
SELECT id FROM app_model WHERE state <> 'F' ORDER BY order LIMIT 3
) AS sub;
但是 Django 不能为你做到这一点。