Django:重复过滤查询集的最有效方法



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

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]
}

最有效的方法是什么?有没有任何方法可以做到这一点,而不必为每个标签使用新的查询进入数据库?

您可以检查prefetch_related,它可能会对您有所帮助:

这与select_related有着相似的目的,因为两者都是为了阻止由于访问相关对象而导致的数据库查询泛滥,但策略完全不同。。。另一方面,prefetch_related对每个关系进行单独的查找,并在Python中进行"连接"。这允许它预取多对多和多对一对象,而这是使用select_related无法完成的。。。

因此,最终您将执行多个查询或使用prefetch_related,它将对对象执行一些Python联接。

您可以这样做:

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

相关内容

  • 没有找到相关文章

最新更新