django按多对多的对象排序

时间:2015-01-31 16:59:47

标签: python django django-queryset

我有一个模特:

class Category(models.Model):
    questions = models.ManyToManyField('Question', related_name="cat_question", blank=True)
    cat_name = models.CharField(max_length=50)
    cat_description = models.CharField(max_length=255)

    def __unicode__(self):
        return self.cat_name

在我看来,我有:

top_categories = Category.objects.all()[:7].

我将它作为模板中的上下文传递。 我想根据问题的数量对顶级类别进行排序,如果一个类别有大多数问题,那么它应该在顶部,如果B有大多数问题那么B。那么第二大等等......

喜欢top_categories = Category.objects.all().order_by(Count(question)

任何帮助?

2 个答案:

答案 0 :(得分:14)

使用问题数注释Category个对象,然后按此编号按降序排序:

from django.db.models import Count

top_categories = Category.objects.annotate(q_count=Count('questions')) \
                                 .order_by('-q_count')[:7]

您可以查看文档order-by中的示例,更多关于aggreagate的示例cheat-sheet

答案 1 :(得分:0)

在这种情况下,他们俩都按照同一字段中的问题数量的顺序对类别进行排序。

但是,您将认识到.annotate()方法还有许多其他用途。例如,您可能希望按问题的数量对类别进行排序,并在日期的下方和日期之间按降序排列。

您可以轻松实现以下目标:

below_50 = Count('questions', filter=Q(marks__gte=50))
top_categories = Category.objects.annotate(below_50=below_50).order_by('-date')

在您的情况下,仅使用order_by是可以的,但是更复杂的查询(求和总数)可能需要.annotate()