【问题标题】:Django - how to retain add order when querying m2m field?Django - 查询m2m字段时如何保留添加顺序?
【发布时间】:2021-04-01 11:05:24
【问题描述】:

我有一个 CustomUser 模型,以及一个通过 m2m 关系引用它的模型:

class CustomUser(AbstractUser):
   ...


class Game(models.Model):
     players = models.ManyToManyField(
        CustomUser, related_name='games',)

当我得到玩家列表时,我希望通过“添加”顺序来接收玩家列表,但是,玩家总是按 CustomUser 表的“id”顺序显示

...即使CustomUser 在模型级别没有排序 而且我在 Django 代码中的任何地方都没有看到AbstractUser 中有任何排序。

user1=CustomUser.objects.get(id=1)
user2=CustomUser.objects.get(id=2)
user3=CustomUser.objects.get(id=3)

game=Game.objects.create()

game.players.add(user3)
game.players.add(user1)
game.players.add(user2)

game.players.all()

总是给user1, user2, user3

如何获取“添加”顺序的m2m记录列表(user3, user1,user2)?

我正在考虑要求通过表中的“id”对查询集进行排序, 但我不知道该怎么做。

有人可以告诉我如何做到这一点吗? ...或者向我提出一个可行的解决方案?

提前致谢

【问题讨论】:

    标签: django django-models many-to-many django-orm m2m


    【解决方案1】:

    好的,在尝试了很多事情之后,我找到了一个令人满意的解决方案,通过通过表中的'id'对查询集进行排序。

    对其他人来说很方便,因为似乎没有很多关于使用隐式直通表的可用知识:

    class Game(models.Model):
         players = models.ManyToManyField(
            CustomUser, related_name='games',)
    
         def get_players(self):
             # need to order_by to order by the id of the through table to ensure the players are listed by order of creation in game table.
             # all other way end up to have the records ordered by user_id instead of order of joining the game
           
             return self.players.through.objects.filter(game_id=self.id).order_by('id')
    

    【讨论】: