Django的ORM如何在性能方面处理以下问题,以及解决问题的最佳方法是什么......
我有两个模型Project
和ProjectVote
。我想在model method
上提供一个Projects
来显示每个项目在显示时的投票数。
但是我很担心!下面的代码似乎只是一个性能消耗。如果我加载所有项目并在每个项目上调用vote_count方法,我猜我会多次击中数据库然后我需要!有没有更好的办法?感谢
class Project(RewardBase):
"""
Represents a Project.
"""
title = models.CharField(max_length=80, help_text="Name of the project")
description = models.TextField(max_length=500)
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
created = models.DateTimeField(blank=True, null=True, editable=False)
def __unicode__(self):
return self.title
def vote_count(self):
"""
Return the number of votes this project has had.
"""
return ProjectVote.objects.filter(project=self.project).count()
class ProjectVote(RewardBase):
"""
Represents a vote for a Project.
"""
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
project = models.ForeignKey('Project', related_name="votes")
答案 0 :(得分:2)
如果您想一次性计算所有项目,请尝试以下查询:
ProjectVote.objects.values("project_id").annotate(count=Count("project_id"))
这应该生成像[{'project_id': 123, 'count': 5}, ...]
这样的结果。您可以将其放在自定义Manager
方法中,该方法可根据您的需要返回适当的数据结构。
另请注意,您的单个项目vote_count
可以简化为self.votes.count()
。
答案 1 :(得分:2)
您可以使用相关Project
的数量为ProjectVote
模型添加注释:
from django.db.models import Count
Project.objects.annotate(vote_count=Count('votes'))
这将在每个vote_count
模型实例上设置Project
属性。这可以与任意数量的过滤器,order_by查询等结合使用。如果您在注释之前过滤了ProjectVote
上的属性(例如votes__user=current_user
),则只会过滤结果出席投票计数。
这将导致单个查询同时获取所有Project
个实例和相关ProjectVote
个实例的计数。