先进的Django查询

时间:2018-08-20 20:18:40

标签: django django-models django-queryset

我有三种模型:公司,资产和用户。每个公司都有许多资产(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个资产,所以这非常慢。似乎最好在数据库级别完成此操作,这使我着眼于注释和聚合,但我无能为力。有人可以指出我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

您可以使用条件进行注释:

from django.db.models import Count, Case, When, IntegerField

qs = Company.objects.filter(asset__owner=self.request.user)
qs = qs.objects.annotate(
    num_assets=Count(Case(
        When(asset__owner=self.request.user, then=1),
        output_field=IntegerField(),
    ))
)

阅读文档conditional-aggregation

答案 1 :(得分:2)

您可以结合使用//This will give me an error return Matches.query(on: request) .join(\Teams.id, to: \Matches.homeTeamID) .alsoDecode(Teams.self) .join(\Teams.id, to: \Matches.awayTeamID) .alsoDecode(Teams.self) .filter(..)

.annotate(..)

因此,这里我们返回一个from django.db.models import Count Company.objects.filter( asset__owner=some_user ).annotate( num_assets=Count('asset') ),其中包含QuerySet个对象,每个对象都有一个额外的属性:Company,其中包含给定用户在该{{ 1}}。

由于在这里-如果我理解正确-资产始终属于单个公司,因此不会出现重复计算的情况:如果是多次交易,许多关系,由属于两个公司的用户拥有的资产,将增加两个公司的数量。

因此,查询集将仅 个返回用户被删除的公司,其中用户拥有个资产,num_assets个用户不拥有的任何资产。