【问题标题】:merge querysets in django在 Django 中合并查询集
【发布时间】:2012-12-20 20:08:42
【问题描述】:

我在models.py:

class Game(models.Model):
    players1 = models.ManyToManyField(Player, related_name='games1')
    players2 = models.ManyToManyField(Player, related_name='games2')

    def get_all_players(self):
        return list(itertools.chain(self.players1.all(), self.players2.all()))

如何编写相同的get_all_players 方法,但返回QuerySet,而不是list

附:我知道有|运营商:

def get_all_players(self):
    return self.players1.all() | self.players2.all()

但它的工作方式非常奇怪。此函数的结果包含的玩家数量多于玩家 1 + 玩家 2 中的玩家数量(结果包含一些玩家的重复)

【问题讨论】:

    标签: python django merge django-queryset


    【解决方案1】:

    对于一个可能在语义上更清晰的解决方案:

    def get_all_players(self):
        return (self.players1.all() | self.players2.all()).distinct()
    

    【讨论】:

    • 这绝对是更干净的解决方案。
    【解决方案2】:

    这应该可以解决问题:

    # On the top of the file:
    from django.db.models import Q
    
    # Game instance method:
    def get_all_players(self):
        return Player.objects.filter(Q(games1__pk=self.pk) | Q(games2__pk=self.pk))
    

    Q在此详细描述:Complex lookups with Q objects

    【讨论】:

    • 非常感谢!我不知道Q 中的games1 会迭代所有游戏。告诉我,你为什么用games1__pk=self.pk 而不是games1=self?这种方式有什么好处吗?
    • @imkost:我已经习惯了。我相信games1=self 可能会隐式转换为games1__pk=self.pk(如果它给你相同的结果)。在参数名称中包含__ 也可以清楚地表明查询中涉及一些JOINs。
    猜你喜欢
    • 2021-01-24
    • 2013-02-22
    • 2017-12-04
    • 2021-11-10
    • 2017-03-09
    • 1970-01-01
    • 2017-11-30
    • 2019-08-11
    • 2013-09-06
    相关资源
    最近更新 更多