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

2024-04-25 09:33:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我想以这样的方式查询一个数据库,而不是仅仅按某个字段排序,而是为该字段的每个唯一值分别获取一个QuerySet(或dictionary、list,whatever)。希望下面的例子能有所帮助:

假设一个模型

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

调用Person.objects.all().order_by('last_name')会给我一个长查询集。我希望每个唯一的姓氏都有一个单独的列表。所以一张名单是给每个姓史密斯的人,另一张名单是给每个姓阮的人等等

显然,我无法提前知道数据库中的姓氏是什么,也无法知道有多少人会共享一个共同的姓氏。在django中,有没有什么快速、高效或自动的方法可以做到这一点,或者我只需要在得到一个大的queryset之后自己处理数据?


Tags: name数据库dictionary排序models方式list例子
3条回答

看看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>

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

您可以获得所有唯一的姓氏:

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

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)

相关问题 更多 >

    热门问题