首页 > 解决方案 > 高级 django 查询

问题描述

我有三个模型:公司、资产和用户。每个公司都有很多资产(ForeignKey),每个资产都有一个用户(ForeignKey,因为一个用户可能拥有多个资产)。

我想运行一个查询,返回给定用户拥有资产的公司列表,以及他们在每个公司中拥有的资产数量。

我曾尝试在 python 中执行此操作,如下所示:

companies = Company.objects.filter(asset__owner=self.request.user)
context['investments'] = [(x, Asset.objects.filter(company=x, owner=self.request.user).count()) for x in companies] 

也许不出所料,这非常慢,因为一家公司可以拥有 100,000 项资产。似乎在数据库级别这样做会更好,这导致我查看注释和聚合,但我无处可去。有人能指出我正确的方向吗?

标签: djangodjango-modelsdjango-queryset

解决方案


您可以通过.filter(..)和的组合来做到这一点.annotate(..)

from django.db.models import Count

Company.objects.filter(
    asset__owner=some_user
).annotate(
    num_assets=Count('asset')
)

所以这里我们返回一个QuerySet包含Company对象的对象,每个对象都有一个额外的属性:num_assets它包含给定用户在该对象中拥有的资产数量Company

因为这里——假设我理解正确——资产总是属于一家公司,所以没有重复计算:如果它是多对多关系,属于两家公司的用户拥有的资产,将有增加了两家公司的数量。

因此,查询集将返回用户拥有资产Company的公司,而没有用户拥有的任何资产的公司因此被过滤掉。


推荐阅读