6

我的站点上的每个用户都有一个模型(UserProfile),每个配置文件都包含一个名为 points 的字段。

我想在按点排序时从当前用户那里获得 -5 +5 用户。我怎样才能做到这一点?

4

2 回答 2

4

您可以进行两个查询,一个针对当前用户之前的用户,一个针对之后的用户:

id = current_user.pk
points = current_user.profile.points

before = User.objects.filter(
    Q(profile__points__gt=points) | 
    Q(profile__points=points, pk__lt=id)
).order_by('-profile__points')[:5]

after = User.objects.filter(
    Q(profile__points__lt=points) | 
    Q(profile__points=points, pk__gt=id)
).order_by('profile__points')[:5]

这是基于两个查询:

  • 得分高于当前用户,或得分相同但得分低于当前用户的所有用户pk
  • 得分低于当前用户的所有用户,或得分相同但得分更高的所有用户pk

然后通过正确的排序和限制,您可以获得结果。当然pk可以用任何其他文件替换,或者完全删除。在后一种情况下,您可以改为认为当前用户始终是第一个(这只是一个示例),并且查询变为:

before = User.objects.filter(
    profile__points__gt=points,
).order_by('-profile__points')[:5]

after = User.objects.filter(
    profile__points__lte=points,
).exclude(pk=id).order_by('profile__points')[:5]

或者,要仅获取按点排序的用户列表中当前用户的索引,您可以执行以下操作:

id = current_user.pk
points = current_user.profile.points
index = User.objects.filter(
    Q(profile__points__gt=points) |
    Q(profile__points=points, pk__lt=id)
).count()

那么以当前用户为中心的用户列表将是:

User.objects.all().order_by('-profile__points', 'pk')[index - 5:index + 6]

如果您有很多用户,这种替代方法可能会更慢,因为需要评估当前用户之前的整个用户列表,但我没有验证这一点。

于 2013-04-21T20:04:26.050 回答
1

我不确定你的观点是什么,但这应该只是注释,如下所示......

from django.db.models import Sum, Avg

UserProfile.objects.annotate(sum_rating=Sum('sum__points')).order_by('-sum_points')

不要忘记您可以在过滤器中使用注释变量。

更新:按点排序,注意-

UserProfile.objects.filter(whatever here).order_by('-points')[:5]

或者

.order_by('points')[:5]
于 2013-04-21T20:06:48.857 回答