Django:按多对多关系字段排序

1 投票
2 回答
2553 浏览
提问于 2025-04-16 07:47

假设你有两个Django模型,分别叫做A和B:

class A(models.Model):
    things = models.ManyToManyField('B')

class B(models.Model):
    score = models.FloatField()
    text = models.CharField(max_length=100)

我该如何获取一个A的列表,并按照在things中得分最高的B的text进行排序呢?

2 个回答

3

这种事情真的很难。如果你想按照分数来排序,聚合(aggregation)可以帮到你:

from django.db.models import Max
A.objects.annotate(highest_b=Max(B__score)).order_by('highest_b')

但实际上你想做两件事:先按最高分进行聚合,然后再按照那个分数对应的文本进行排序。这无论用什么语言来做都挺棘手的。我在我的博客上写过这个问题——对你来说,我觉得通过.raw()方法在SQL中实现可能是最简单的。

2

如果我理解得没错,这段代码应该可以实现你的需求。list 会包含模型 A 中所有对象的列表,这些对象是按照每个对象得分最高的内容的文本进行排序的。

dict = {}
list = []
for a in A.objects.all():
    dict[a] = a.things.all().order_by("-score")[0].text
for k, v in sorted(dict.items(), key=lambda x: x[1]):
    list.append(k)

可能还有更好看的写法,但我现在想不起来...

撰写回答