显示具有ManyToMany关系的排序列表

时间:2014-01-08 22:51:31

标签: django view model relation sorted

我有一定数量的ob主题和用户。用户可以投票给一个或多个主题。我想制作一个视图,显示排序顺序中排名前10位的主题。

事实上,我找到了一种工作方式,但我问自己是否有更合适的方法来做到这一点。

我从模特开始:

class Subject(models.Model):
    text = models.TextField()

class User(models.Model):
    name = models.CharField(max_length=64)
    subject = models.ManyToManyField(Subject)

现在我可以输入:

Subject.user_set.all()

我会得到那些投票赞成该主题的用户。

现在我想制作一个列表视图,其中前10个主题将按投票数排序。 所以我在Subject类中添加了一个类方法:

class Subject(models.Model):
    text = models.TextField()

    @staticmethod
    def by_votes():
        myList = list(Subject.objects.all())
        return sorted(myList, key=lambda s: s.user_set.count(), reverse=True)[:10]

并定义了基于类的视图:

class SubjectListView(ListView):
    model = Subject
    template_name = "subject_list.html"
    context_object_name = "subject_list"
    queryset = Subject.by_votes()

哪种方法效果很好。 但是我在docs Manager和QuerySet类中看到,遗憾的是我不太明白如何使用它们(定义自定义的)来获取我正在寻找的东西(不处理原始SQL查询)。

我有点害怕,因为我使用了一个列表,我可能遇到有大量主题的内存问题。 你会怎么说,更适合使用自定义Manager或者QuerySet,不会吗? 如果是的话,该怎么做?

还有其他想法吗?

谢谢! 彼得

2 个答案:

答案 0 :(得分:1)

我对此很新,但我解决了类似的问题:

Subject.objects.all().annotate(count=Count('user')).order_by('-count')[:10]

Aggregation Doc

答案 1 :(得分:1)

这里不需要自定义管理器或原始SQL,只需聚合。

from django.db.models import Count
Subject.objects.annotate(user_count=Count('user').order_by('-user_count')[:10]