Django ORM 按表达式排序

Django ORM order by expression

嗨,我可以在 ORM 中按 < 2 订购 我唯一的想法是:

players = GamePlayer.objects.raw('SELECT * FROM `Farmer_gameplayer` WHERE (`Farmer_gameplayer`.`game_id` = %d) ORDER BY `turn` < %d' % (game.pk, game.turn))

我想点这个:

players = GamePlayer.objects.filter(game=game) ORDER BY `turn` < 2

注意: 您可以调整您的应用程序以使用 ORDER BY turn,因为 定性 结果set 与 ORDER by turn < 2 没有太大区别。您会看到不同之处仅在于 ORDER BY turn 会根据它们的 turn 列更改所有行的排序,而 ORDER BY turn < 2 按布尔表达式 turn < 2 排序,这不会t 重新排序除此之外的所有行。 下面我将介绍如何使用表达式对 Django 查询集进行排序,例如turn < 2

用表达式注释,然后按它排序:

这个想法是注释一个名为 turn_is_less_than_2 的字段 either True or False,然后按它排序。所述注释将表示您稍后要排序的表达式 turn < 2 (ORDER BY turn < 2)

from django.db.models import Case, When, BooleanField

GamePlayer.objects.filter(game=game).annotate(turn_is_less_than_2=Case(
    When(turn__lt=2, then=True),
    default=False,
    output_field=BooleanField()
)).order_by('turn_is_less_than_2') 

# or order_by('-turn_is_less_than_2') for DESC order instead of ASC

分解解释:

首先我只是在回答你的问题

GamePlayer.objects.filter(game=game)

然后我做的是用字段 turn_is_less_than_2 注释它,如果 turn < 2 则为 True,否则为 False

GamePlayer.objects.filter(game=game).annotate(turn_is_less_than_2=...)

然后当我们注释了过滤的查询集后,我们现在可以order_by那个字段:

GamePlayer.objects.filter(game=game).annotate(...).order_by('turn_is_less_than_2')