拆分查询集或按字段获取多个查询集,而不是按字段排序

时间:2012-07-09 01:59:26

标签: python django models

我想以一种方式查询数据库,而不是仅仅按某个字段排序,我为该字段的每个唯一值得到一个单独的QuerySet(或字典,列表,无论如何)。希望以下示例有所帮助:

假设像

这样的模型
Class Person(models.Model):
   first_name = models.CharField()
   last_name = models.CharField

调用Person.objects.all()。order_by('last_name')给我一个长的QuerySet。我希望为每个唯一的last_name设置一个单独的列表。因此,每个人的一个列表,其中last_name =“Smith”,另一个列表,每个人的last_name =“Nguyen”等。

显然我不能提前知道last_names在数据库中的内容,也不知道有多少人会共享一个共同的last_name。是否有任何快速,有效或自动的方法在django中执行此操作,或者我只需要在获取一个大型查询集后自己处理数据?

3 个答案:

答案 0 :(得分:10)

samy的代码是正确的,但效率很低:你做n + 1次查询(其中n是唯一姓氏的数量)。既然你要获得表格中的所有对象,你也可以一次性完成它。请改用:

from collections import defaultdict
person_dict = defaultdict(list)
persons = Person.objects.all()
for person in persons:
    person_dict[person.last_name].append(person)

答案 1 :(得分:4)

查看regroup标记。

{% regroup persons by last_name as surname_list %}

<ul>
{% for last_name in surname_list %}
    <li>{{ last_name.grouper }}
    <ul>
        {% for person in last_name.list %}
          <li>{{ person.last_name }}, {{ person.first_name }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>

(此代码未经测试,请阅读文档并自行解决任何问题)

答案 2 :(得分:1)

你可以获得所有独特的姓氏:

from django.db.models import Count
...
last_names = Person.objects.values('last_name').annotate(Count('last_name')) # This will return all the unique last_names
values = dict( ((last_name['last_name'], Person.objects.all().filter(last_name = last_name['last_name'])) for last_name in last_names if last_name['last_name__count']) )
# This will create a dictionary where the keys are all the unique names and the values are querysect of all the values that have that lastname

丹尼尔 - 罗斯曼是对的,这是非常低效的,所以继承人的调整版......

from collections import defaultdict
values = defaultdict(list)
_ = map(lambda person: values[person.last_name].append(person), Person.objects.all())

请注意_ = ...是这样我们不会在终端上打印所有None;)