首页 > 解决方案 > Django - 获取按不同属性分组的查询集列表对象属性

问题描述

假设我有这个模型:

class MyModel(models.Model):
    state = models.CharField(max_length=2)
    SKU = models.PositiveIntegerField()

和这些价值观:

MyModel.objects.create(state='CA', SKU=1)
MyModel.objects.create(state='CA', SKU=2)
MyModel.objects.create(state='NY', SKU=3)

我的目标是创建一个字典,将状态映射到这些对象的 SKU 列表。我试图这样做:

my_objs = MyModel.objects.values('state', 'SKU')  # to prevent creation of python object on loop -- my real model has many more fields that I don't need to query
state_to_skus = dict()
for my_obj_dict in my_objs:
    state_to_skus.setdefault(my_obj_dict['state']).append(my_obj_dict['SKU'])

这产生了我:

{'CA': [1, 2], 'NY': [3]}

这正是我想要的,但是,当查询近 100 万个条目时,它并没有按我的意愿扩展。有没有更有效的方法来创建这个字典作为 QuerySet 是这样的?

<QuerySet [{'state': 'CA', 'SKUs': [1,2]}, {'state': 'NY', 'SKUs': [3]}]>

我还回顾了这个问题:Django - How to get a list of queryset grouped by attribute value 然而,这两个答案都不是我需要的;它们仍然可以扩展到相同的复杂性。

谢谢!

标签: pythondjangopython-3.xdjango-models

解决方案


我能想到的最好的方法是按状态对记录进行排序,然后itertools.groupby()按状态对它们进行分组。如果您使用QuerySet.iterator(),那么我认为您可以避免将所有 100 万条记录加载到内存中。在状态字段上添加索引可能会缩短排序时间。

如果您仍然对性能不满意,我建议您在问题中添加模型和查询的最小版本,并解释您希望获得什么样的性能。


推荐阅读