【问题标题】:Ordering a query set based on the length of another query set根据另一个查询集的长度对查询集进行排序
【发布时间】:2016-06-07 23:48:56
【问题描述】:

我有这些模型:

class Team(models.Model):
    # stuff

class Alliance(models.Model):
    teams = models.ManyToManyField(Team)

class Match(models.Model):
    alliances = models.ManyToManyField(Alliance)
    winner = models.ForeignKey(Alliance, null=True, related_name='winner')

我正在尝试按Teams 排序获得最多胜利的列表。我目前有这个算法,它有效,但速度很慢:

from collections import Counter
def most_match_wins(n=None):
    matches = Match.objects.filter(winner__isnull=False)
    count = Counter()
    for m in matches:
        for team in m.winner.teams.all():
            count[team] += 1

    return count.most_common() if n is None else count.most_common(n)

我现在正在尝试使用 Django 提供的聚合/注释来改进它。然而,我遇到了一个障碍。我可以通过执行以下查询来检索Team 的获胜次数:

Match.objects.filter(winner__in=my_team_object.alliance_set.all()).count()

现在我不知道从这里去哪里。 django.db.models.Count 似乎没有提供我正在寻找的功能,django.db.models.F / django.db.models.Q 也是如此。

任何帮助将不胜感激。也许我只是没有正确考虑 F/Q 对象。

【问题讨论】:

  • 您要订购哪个清单?团队,联盟?

标签: python mysql django performance python-3.x


【解决方案1】:

您似乎正在尝试根据获胜次数对团队进行排序。在这种情况下,您可以为每个 Team 对象标注其相关联盟的获胜次数,然后按降序对这些获胜次数进行排序:

from django.db.models import Count
teams = Team.objects.annotate(num_wins=Count('alliance__winner')).order_by('-num_wins')

【讨论】:

  • 天哪,我认为做到了。这是一个很好的例子,我将来也可以继续使用。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
相关资源
最近更新 更多