Django:过滤查询集的最有效方法是什么?

3

我有一个模型,看起来像这样:

class Item(models.Model):
    name = models.CharField()
    type = models.CharField()
    tags = models.models.ManyToManyField(Tags)

为了呈现给定的视图,我有一个基于类型呈现项目列表的视图。因此,在我的视图中,有一个查询,例如:
items = Item.objects.filter(type='type_a')

那很容易和直接。现在我有一个额外的视图要求。为了满足该要求,我需要构建一个将标签与项目相关联的字典。因此,我期望的输出应该类似于:

{
    'tag1': [item1, item2, item5],
    'tag2': [item1, item4],
    'tag3': [item3, item5]
}

如何最有效地完成这个任务?有没有办法在不为每个标签发出新查询的情况下完成?

2个回答

3
您可以查看prefetch_related,它可能会对您有所帮助:
这与select_related有相似的目的,因为两者都旨在防止访问相关对象而引起的数据库查询洪流,但策略是非常不同的...另一方面,prefetch_related为每个关系执行单独的查找,并在Python中执行“连接”。这使得它能够预获取多对多和多对一对象,而使用select_related无法完成...
因此,最终您要么执行多个查询,要么使用prefetch_related并对对象进行一些Python连接。

2
你可以这样做:
# This should require two database queries, one for the items 
# and one for all the associated tags.
items = Item.objects.filter(type='type_a').prefetch_related('tags')

# Now massage the data into your desired data structure.
from collections import defaultdict
tag_dict = defaultdict(list)
for item in items:
    # Thanks to prefetch_related this will not hit the database.
    for tag in item.tags.all():
        tag_dict[tag].append(item)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接