从Django查询集中获取第一个对象

3

给定以下代码:

randomItemQS = Item.objects.filter().exclude(id__in=[o.id for o in collection]).order_by('?')
randomItem = randomItemQS[:1]
calculation = randomItem.method() / constant

我该如何确保randomItem是一个Item而不是一个QuerySet?

如果我在manage.py shell中运行代码,则会得到预期的结果。但是,从视图运行此代码会导致AttributeError'QuerySet' object has no attribute 'method',并指示错误发生在最后一行。

我错过了什么吗?

编辑:抱歉,我应该更具体一些——我在shell中可以正常工作,但在视图中无法正常工作。有什么不同吗?


请参考 Pavel 的下面的答案。 - Matthew Calabresi
1
不相关,但是如果collection本身就是一个queryset,那么你应该直接使用exclude(id__in=collection),它使用子查询并且无需单独评估collection - Daniel Roseman
collection 是一个列表,感谢反馈。 - Matthew Calabresi
3个回答

3
只需对其进行索引,切片即可向QS添加LIMIT查询,而不执行它:
randomItem = randomItemQS[0]

由于某种原因,这会将错误消息更改为“IndexError:list index out of range”。不确定为什么... QuerySet返回超过150个对象。 - Matthew Calabresi
你确定吗?print randomItemQS.count() - Pavel Anossov

1
你可以做到这一点:

randomItem=None
randomItemQS = Item.objects.filter().exclude(id__in=[o.id for o in collection]).order_by('?')[:1]
if randomItemQS:
   randomItem = randomItemQS[0]
   calculation = randomItem.method() / constant

0
由于问题涉及视图和 shell 窗口之间的区别,正确答案是将传递给视图的参数转换为整数,以确保查询按预期返回对象。
其他答案已被相应地投票,因为它们是有效的。谢谢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接