这可以减少为单个查询吗?

Can this be reduced to a single query?

我有一个带有字段 position = PositiveIntegerField(unique=True) 的模型。给定此模型的一个实例,我想获得具有下一个最高位置的实例(受某些过滤器的约束)。如果这个实例是位置最高的那个,我想环绕到 0 和 return 位置最低的实例;如果这个实例是唯一的,我想 return 本身。

这是我的代码:

count = Player.objects.count()
return Player.objects.filter(game_id=self.game_id, is_alive=True).annotate(
    relative_position=(F('position') - self.position - 1 + count) % count
).order_by('relative_position')[:1].get()

+ count的原因是因为负数对正数的模在SQL中是负数。)

这需要两次数据库查询。我怀疑使用 annotateCount 仅在一个查询中就可以做到这一点,但我还没有弄清楚如何将这样的查询放在一起。可以做到吗?如果可以,怎么做?

不一定总是一个查询,但它可能胜过 2 个查询和注释:

players = Player.objects.filter(game_id=self.game_id, is_alive=True).order_by('position')
try:
    return players.filter(position__lt=self.position)[0]
except IndexError:
    return players.last()

我发现条件查询表达式是 Django 1.8 中的一个东西,这意味着我可以放弃模运算并这样做:

return Player.objects.filter(game_id=self.game_id, is_alive=True).order_by(
    Case(When(position__gt=self.position, then=Value(0)), default=Value(1)),
    'position'
)[:1].get()