Django按字段聚合,没有相关名称

时间:2016-07-25 20:30:25

标签: django

鉴于这些模型:

class User(models.Model):
    pass

class Reward(models.Model):
    user = models.ForeignKey(User, related_name='+')

我正在尝试获取包含类似内容的QuerySet:

| user    | reward__count |
| 1       | 103           |
| 2       | 50            |
| 3       | 67            |

Conventional wisdom会推荐一个类似

的查询
User.objects\
    .annotate(reward__count=Count('reward_set'))\
    .values_list('user', 'reward__count')

不幸的是,由于相关名称为+,因此reward_setrewards(如果我可以为其命名)都不符合Count()的有效参数。鉴于这种情况,除了python for循环之外,除了获得所需的QuerySet之外真的没办法吗?

for user in User.objects.all():
    user_rewards = Reward.objects.filter(user=user).count()
    # Store (user.pk, user_rewards) somewhere.

2 个答案:

答案 0 :(得分:5)

  

我正在尝试获取包含类似内容的QuerySet:

| user    | reward__count |
| 1       | 103           |
| 2       | 50            |
| 3       | 67            |

您可以在Reward对象上使用aggregations

# Fetch a list of rewards, grouped by
rewards = Reward.objects.values('user').annotate(Count('id')).order_by()

这将为您提供如下列表:

[
    {'user': 1, 'id__count': 103}, 
    {'user': 2, 'id__count': 50}, 
    {'user': 3, 'id__count': 67},
    ...
]

其中user是用户ID,id__count是与该用户关联的奖励数。

答案 1 :(得分:4)

@solarissmoke发布了一个很好的答案我赞成,我想提出一个替代方案吗?一个unmanaged model

创建一个非托管模型,该模型指向与不可触摸的库应用程序中的表相同的表。

class RewardOnSteroids(models.Model):
    user = models.ForeignKey(User, related_name='pick something')

    class Meta:
        managed = False
        db_table = 'original table name'