如何统计与ListView中项目相关的对象?
我正在尝试使用一个列表视图来显示我所有的城镇。
不过,我想为每个城镇显示一下住在那里的公民数量。
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
属性。