我有一个模型类“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
答案 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]
这和你之前做过的一样,但我只是正确使用了列表推导。