【问题标题】:Django complex query for a leaderboard using Q使用 Q 的 Django 复杂查询排行榜
【发布时间】:2021-05-27 20:00:04
【问题描述】:

我的模型是这样的:

class User(AbstractUser):
    ...

class UserPoints(models.Model):
    user = models.ForeignKey(User, relative_name='points')
    earned_points= models.IntegerField()
    reward_month = models.IntegerField(default=0)
    reward_year = models.IntegerField(default=0)

每个月都会创建UserRewards。我正在使用 Q 生成查询。

我要做的是列出前10名用户,按照earned_points的总和排列。 UserRewards 将被过滤为仅包含最近三个月的值。我知道如何单独执行过滤、聚合、注释和求和。但是在单个查询或组合两个查询中,我似乎无法准确计算出来,尤其是当每个用户有多个 UserRewards 时。

【问题讨论】:

  • UserPoints 你所说的UserRewards 吗?到目前为止,您尝试过什么?
  • 如果我的回答有用请考虑accepting它。

标签: python django-rest-framework django-q


【解决方案1】:

我已将您的模型修复为具有on_delete 属性并将relative_name 更正为related_name,如下所示:

class UserPoints(models.Model):
    user = models.ForeignKey(User, related_name='points', on_delete=models.CASCADE)
    earned_points = models.IntegerField()
    reward_month = models.IntegerField(default=0)
    reward_year = models.IntegerField(default=0)

然后我添加了一些测试数据:

>>> up = UserPoints(user=User.objects.get(pk=1), earned_points=10, reward_month=2, reward_year=2021)
>>> up.save()
>>> up = UserPoints(user=User.objects.get(pk=1), earned_points=15, reward_month=1, reward_year=2021)
>>> # up assignment and up.save() omitted from here on...
>>> UserPoints(user=User.objects.get(pk=2), earned_points=5, reward_month=1, reward_year=2021)
>>> UserPoints(user=User.objects.get(pk=3), earned_points=7, reward_month=2, reward_year=2021)
>>> UserPoints(user=User.objects.get(pk=3), earned_points=3, reward_month=1, reward_year=2021)

现在我们可以像这样对UserPointsUser 进行求和和排名:

from django.db.models import Sum
for user in User.objects.all() \
        .annotate(earned_points_sum=Sum('points__earned_points')) \
        .filter(earned_points_sum__gt=0) \
        .order_by('-earned_points_sum'):
    print(user.pk, user.earned_points_sum)

输出:

1 25
3 10
2 5

【讨论】:

    猜你喜欢
    • 2016-06-06
    • 2020-05-26
    • 2021-01-17
    • 2015-01-22
    • 1970-01-01
    • 2023-03-17
    • 2021-07-17
    • 2013-04-12
    • 1970-01-01
    相关资源
    最近更新 更多