2012-01-27 59 views
1

我有一个模型类“地方”,它有一个“状态”的字段,我想获得由数据库中所有可用的不同状态分组的查询集列表。在django中创建查询集列表的最佳方式是什么?

我目前这样做:

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

是否有更好的aggregate命令我可以用这个优化?什么是最好的方法来做到这一点?

〜使用Python 2.6,Django的1.3.1

+6

如果您计划在模板级别显示这些内容,则可以使用“regroup”标记:https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#regroup – 2012-01-27 00:45:26

+0

谢谢pastylegs!这是有用的 – Priyeshj 2012-01-27 17:33:21

回答

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

这仅命中一次数据库,而不是每个国家像你的原始版本(假设你使用所有的结果),但你最终名单的列表,而不是查询集的列表。

+0

*在Django中创建查询集列表的最佳方式是什么?*我没有在这里看到**列表的查询集** – juliomalegria 2012-01-27 01:01:35

+0

@ julio.alegria好点 - 现在有一个列表清单。如果你真的想要查询集对象而不是列表,你的/ [istrubble的答案](http://stackoverflow.com/a/9027755/344821)当然是正确的方法。 – Dougal 2012-01-27 01:04:23

+0

我认为你应该把它改为'places_by_state [place.state] .append(place)' – juliomalegria 2012-01-27 01:06:04

0

你没有正确使用列表理解。列表理解不是重复动作,而是创建列表。所以这个我会做什么:

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

这只是你之前做的一样,但我只是使用列表理解正确。

+0

感谢胡里奥的更正和其他意见:) – Priyeshj 2012-01-27 17:19:08

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] 

这仍然打州+ 1次的DB计数,但你只在一开始进行的状态查询。 place_list中的QuerySet对象仍然是懒惰的,直到您使用它们才会被评估。

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

+0

谢谢istruble!这对我有效。从外观上看,重组也是一个非常方便的工具 – Priyeshj 2012-01-27 17:19:55

相关问题