在django中创建查询集列表的最佳方法是什么?

时间:2012-01-27 00:41:17

标签: python django

我有一个模型类“Place”,它有一个“state”字段,我想得到一个按DB中所有可用的不同状态分组的查询集列表。

我目前正在这样做:

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 :(得分:3)

如何获得状态的值(values_list是一个方便的工具):

states = Place.objects.values_list('state', flat=True).distinct()

然后执行您为每个州执行的操作但使用list comprehension的结果并跳过.append()调用。

place_list = [Place.objects.filter(state=state) for state in states]

这仍然会达到状态的DB计数+ 1次,但您只是在开始时执行状态查询。 place_list中的QuerySet对象仍然是惰性的,在您使用它们之前不会被评估。

注意:@pastylegs关于在模板中使用regroup模板标记的评论可能是我们任何人所说的最具洞察力的事情。我的回答只是向您展示value_list和列表推导。

答案 1 :(得分:2)

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()

只能访问数据库一次,而不是像原始版本一样每个状态一次(假设您使用了所有结果),但最终得到的是列表而不是查询集列表。

答案 2 :(得分:0)

您没有正确使用列表推导。列表理解不是用于重复动作,而是用于创建列表。所以这就是我要做的事情:

places = Place.objects.distinct('state')
place_list = [Place.objects.filter(state=p.state) for p in places]

这和你之前做过的一样,但我只是正确使用了列表推导。