使用iterator()时,Django'generator'对象不可订阅

时间:2012-05-09 21:12:50

标签: django iterator

我试图通过在我的查询集上使用iterator()来节省内存,从而优化我的Web应用程序。

但是,如果我这样做:

q = (
    Q(longname__icontains = query) |
    Q(genus__icontains = query) |
    Q(specific_epithet__icontains = query) |
    Q(infraspecific_epithet__icontains = query) |
    Q(collectedby__personname__icontains = query) |
    Q(islandname__icontains = query) |
    Q(es_name__icontains = query) |
    Q(en_name__icontains = query) |
    Q(local_name__icontains = query)
)
query_set = Specimen.objects.filter(q).order_by('longname').iterator()[:1000]

我收到以下错误:

TypeError at /search/
'generator' object is not subscriptable

如果我尝试:

query_set.count()

我明白了:

AttributeError at /search/
'generator' object has no attribute 'count'

我的问题是 - 如何在这种类型的查询中使用迭代器,它真的值得吗?

任何帮助都非常感激。

2 个答案:

答案 0 :(得分:1)

您可以使用itertools.islice()切片生成​​器。您需要执行单独的COUNT(*)查询以获取返回的记录总数。

答案 1 :(得分:1)

iterator()将QuerySet转换为生成器对象,该对象不再是可订阅的,并且没有.count()方法。
在将QuerySet转换为生成器之前,切片和其他特定于QuerySet的操作也是如此(之后您只能通过迭代来访问生成器):

query_set = Specimen.objects.filter(q).order_by('longname')[:1000].iterator()

或者你可以像Ignacio建议的那样对发电机进行操作

query_set = Specimen.objects.filter(q).order_by('longname').iterator()
from itertools import islice
g = islice(query_set, 1000)