Python 在Django ORM中从外键获取计数的更好方法

Python 在Django ORM中从外键获取计数的更好方法,python,django,django-orm,Python,Django,Django Orm,Django的ORM在性能方面如何处理以下问题,解决我的问题的最佳方法是什么 我有两个模型Project和ProjectVote。我想在项目上提供一个模型方法,以显示每个项目在显示时的投票数 不过我很担心!下面的代码看起来像是性能消耗。如果我在所有项目中加载,并在每个项目上调用vote_count方法,我猜这会多次击中DB,然后我需要!有更好的办法吗?谢谢 class Project(RewardBase): """ Represents a Project. """

Django的ORM在性能方面如何处理以下问题,解决我的问题的最佳方法是什么

我有两个模型
Project
ProjectVote
。我想在
项目
上提供一个
模型方法
,以显示每个项目在显示时的投票数

不过我很担心!下面的代码看起来像是性能消耗。如果我在所有项目中加载,并在每个项目上调用vote_count方法,我猜这会多次击中DB,然后我需要!有更好的办法吗?谢谢

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")

如果要一次性统计所有项目,请尝试以下查询:

ProjectVote.objects.values("project_id").annotate(count=Count("project_id"))
这将生成类似于
[{'project\u id':123,'count':5},…]的结果。您可以将其放在自定义的
管理器
方法中,该方法返回适合您需要的数据结构


还要注意的是,您的单个项目
投票计数
可以简化为
self.vots.count()

如果要一次性统计所有项目,请尝试以下查询:

ProjectVote.objects.values("project_id").annotate(count=Count("project_id"))
这将生成类似于
[{'project\u id':123,'count':5},…]的结果。您可以将其放在自定义的
管理器
方法中,该方法返回适合您需要的数据结构


还请注意,您的单个项目
投票计数
可以简化为
self.voces.count()
您可以使用相关的
项目投票数对
模型进行注释,如下所示:

from django.db.models import Count

Project.objects.annotate(vote_count=Count('votes'))
这将在每个
项目
模型实例上设置一个
投票计数
属性。这可以与任意数量的过滤器、按查询排序等组合使用。如果在注释之前对
ProjectVote
上的属性进行过滤(例如
voces\uuuu user=current\u user
),则投票计数中将只显示过滤后的结果


这将导致一个查询,该查询将获取所有
Project
实例和相关
ProjectVote
实例的计数

您可以使用相关的
ProjectVote
s编号对
Project
模型进行注释,如下所示:

from django.db.models import Count

Project.objects.annotate(vote_count=Count('votes'))
这将在每个
项目
模型实例上设置一个
投票计数
属性。这可以与任意数量的过滤器、按查询排序等组合使用。如果在注释之前对
ProjectVote
上的属性进行过滤(例如
voces\uuuu user=current\u user
),则投票计数中将只显示过滤后的结果


这将导致一个查询,该查询将获取所有
Project
实例和相关
ProjectVote
实例的计数

总结此方法与@knbk之间的区别:如果您需要访问
项目
,无论是用于筛选还是事后,请使用该技术;如果没有(也就是说,如果您只需要
项目
ID),请使用此ID,因为它避免了额外的
连接
。总结此方法与@knbk之间的区别:如果您需要访问
项目
,无论是用于筛选还是事后,请使用该技术;如果没有(也就是说,如果您只需要
项目
ID),请使用此ID,因为它避免了额外的
连接