gpt4 book ai didi

python - value_list django 是如何工作的?

转载 作者:行者123 更新时间:2023-12-01 03:19:50 25 4
gpt4 key购买 nike

我在 value_list 方面有过有趣的经历,但我不知道它为什么会这样。

我想将 TestObject 中具有 value_1 的任何值更新为 value_2,并将任何 value_2 更新为 value_1。其中 Value 类型的 value_1value_2 以及 TestObject 具有 Value 的外键。

这是我的代码:

def _swap(value_1, value_2):
from_values_ids = TestObject.objects.filter(value=value_1).values_list('id', flat=True)

to_values_ids = TestObject.objects.filter(value=value_2).values_list('id', flat=True)

TestObject.objects.filter(id__in=from_values_ids).update(value=value_2)
TestObject.objects.filter(id__in=to_values_ids).update(value=value_1)

我使用 TestObject 进行测试,有 value_1,但没有任何 value_2。运行该函数后的最终结果是没有任何反应。经过调查,我发现 TestObject 在运行后更新为 value_2:

TestObject.objects.filter(id__in=from_values_ids).update(value=value_2)

但是运行后又返回了

TestObject.objects.filter(id__in=to_values_ids).update(value=value_1)

我认为可能是 to_values_ids 具有延迟加载,这就是我添加 print to_values_id 的原因。

def _swap(value_1, value_2):
from_values_ids = TestObject.objects.filter(value=value_1).values_list('id', flat=True)

to_values_ids = TestObject.objects.filter(value=value_2).values_list('id', flat=True)

print to_values_ids

TestObject.objects.filter(id__in=from_values_ids).update(value=value_2)
TestObject.objects.filter(id__in=to_values_ids).update(value=value_1)

但我得到了相同的结果。虽然我的 to_values_ids 打印有 []

我修复它的方法是使用 ids 创建新列表,它可以工作,但仍然需要了解核心 python 它是如何工作的?有什么好的解释吗?

最佳答案

您看到的问题可能是由于 Django QuerySet value_lists 返回生成器所致。从 1.9 开始,QuerySet.values_list 实现了一个可迭代类,如 FlatValuesListIterable在 1.9 之前,QuerySet.values_list 返回 ValuesListQuerySet 的实例...这两个都返回一个生成器,因此每次访问变量时都会执行查询(因此您在调用 print 时看到的行为)。

生成的对象的行为很像列表,这很令人困惑,但如果您需要证明它不是列表,请尝试以下操作:

from_values_ids = TestObject.objects.filter(value=value_1).values_list('id', flat=True)
from_list_ids = [obj.id for obj in TestObject.objects.filter(value=value_1)]
combined_list = from_values_ids + from_list_ids

...这将导致:

TypeError: unsupported operand type(s) for +: 'ValuesListQuerySet' and 'list'

解决方案只需将 from_values_ids 变量转换为列表即可:

from_values_ids = list(TestObject.objects.filter(value=value_1).values_list('id', flat=True))

或者自己生成列表:

from_values_ids = [obj.id for obj in TestObject.objects.filter(value=value_1)]

关于python - value_list django 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42030864/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com