如何统计与ListView中项目相关的对象?

1 投票
2 回答
936 浏览
提问于 2025-04-20 07:49

我正在尝试使用一个列表视图来显示我所有的城镇。

不过,我想为每个城镇显示一下住在那里的公民数量。

Models.py

class Town(models.Model):
    name = models.CharField()

class Citizen(models.Model):
    name = models.CharField()
    town = models.ForeignKey(Town)

Views.py

class TownView(ListView):
    model = Town
    def get_context_data(self, **kwargs):
        context = super(TownView, self).get_context_data(**kwargs)
        context['towns'] = Town.objects.all().prefetch_related('players')
        return context

这样做不行,因为预取关联(prefetch_related)只有在城镇视图中有一个玩家属性时才有效,可能是通过一个多对多的字段。

我该如何获取每个城镇的公民数量呢?这些公民的外键是指向那个城镇的。

另外,我的模板应该是什么样子的呢?目前,它看起来是这样的:

模板

<table>
{% for town in open_towns %}
    <tr>
        <td><a href="/town/join/{{ town.slug }}/">{{ town.name }}</a></td>
        <td>population : {{ Player.objects.filter(town=town).count() }}</td>
    </tr>
{% endfor %}
</table>

但这显然也是错的。

2 个回答

3

看起来你需要的是annotate这个功能:

Town.objects.annotate(population=Count('players'))

然后在模板中:

<table>
{% for town in open_towns %}
    <tr>
        <td><a href="/town/join/{{ town.slug }}/">{{ town.name }}</a></td>
        <td>population : {{ town.population }}</td>
    </tr>
{% endfor %}
</table>
5

你这里其实需要的是注解。你可以不重写任何方法就做到这一点。

from django.db.models import Count

class TownView(ListView):
    queryset = Town.objects.all().annotate(citizen_count=Count('citizen'))

现在,object_list中的每个元素都有一个citizen_count属性。

撰写回答