7

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

假设一个模型像

Class Person(models.Model):
   first_name = models.CharField()
   last_name = models.CharField

调用 Person.objects.all().order_by('last_name') 会给我一个长查询集。相反,我希望为每个唯一的姓氏创建一个单独的列表。因此,每个带有 last_name="Smith" 的 Person 的列表和每个带有 last_name="Nguyen" 的 Person 等的列表。

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

4

3 回答 3

13

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)
于 2012-07-09T08:52:35.083 回答
8

查看重组标签。

{% 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>

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

于 2012-07-09T02:43:19.140 回答
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在终端上打印所有内容;)

于 2012-07-09T02:47:17.197 回答