我有一定数量的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,不会吗? 如果是的话,该怎么做?
还有其他想法吗?
谢谢! 彼得
答案 0 :(得分:1)
我对此很新,但我解决了类似的问题:
Subject.objects.all().annotate(count=Count('user')).order_by('-count')[:10]
答案 1 :(得分:1)
这里不需要自定义管理器或原始SQL,只需聚合。
from django.db.models import Count
Subject.objects.annotate(user_count=Count('user').order_by('-user_count')[:10]