2015-04-22 39 views
0

我有一個字段爲position = PositiveIntegerField(unique=True)的模型。給定這個模型的一個實例,我想獲得下一個最高位置的實例(取決於某些過濾器)。如果這個實例是位置最高的實例,我想繞回0並返回最低位置的實例;如果這個實例是唯一的,我想返回它自己。這可以簡化爲單個查詢嗎?

這裏是我的代碼:

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,但我還沒有弄清楚如何將這樣的查詢放在一起。它可以完成,如果是這樣,如何?

回答

0

我發現,條件查詢表達式是在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() 
0

並不總是隻有一個查詢,但它可能擊敗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()