在Django中创建查询集列表的最佳方法是什么?
我有一个模型类叫“Place”,里面有一个字段是“state”,我想要获取一个按数据库中所有不同状态分组的查询结果列表。
我现在是这样做的:
place_list = []
places = Place.objects.distinct('state')
[place_list.append( Place.objects.filter(state=p.state) ) for p in places]
有没有更好的聚合命令可以用来优化这个?这样做的最佳方式是什么?
~ 使用 Python 2.6,Django 1.3.1
3 个回答
0
你没有正确使用列表推导式。列表推导式不是用来重复动作的,而是用来创建列表的。所以我会这样做:
places = Place.objects.distinct('state')
place_list = [Place.objects.filter(state=p.state) for p in places]
这和你之前做的其实是一样的,只是我正确地使用了列表推导式。
3
你可以先获取所有州的值(这里的values_list
工具非常好用):
states = Place.objects.values_list('state', flat=True).distinct()
然后对每个州做你之前做的事情,不过这次用你之前的列表推导式的结果,省去 .append() 这个步骤。
place_list = [Place.objects.filter(state=state) for state in states]
这样虽然还是会查询数据库,次数是州的数量加一,但你只是在一开始就执行了查询。place_list
中的查询集对象会保持懒加载,直到你真正使用它们时才会被计算出来。
注意:@pastylegs 提到的在模板中使用regroup
标签的建议,可能是我们说过的最有见地的内容。我的回答主要是想让你了解一下 values_list
和列表推导式。
3
from collections import defaultdict
places_by_state = defaultdict(list)
for place in Place.objects.all():
places_by_state[place.state].append(place)
list_of_places_by_state = places_by_state.values()
这样做只会让数据库查询一次,而不是像你原来的版本那样每个状态都查询一次(假设你用到了所有的结果)。不过,这样你得到的结果是一个列表的列表,而不是一个查询集的列表。